Go to the documentation of this file.
36 #include "libmythbase/mythversion.h"
67 const QString &sTitleRegEx,
68 const QString &sRecGroup,
69 const QString &sStorageGroup,
70 const QString &sCategory,
76 QMap< QString, ProgramInfo* > recMap;
90 if (bIgnoreLiveTV && (sRecGroup ==
"LiveTV"))
92 bIgnoreLiveTV =
false;
93 LOG(VB_GENERAL, LOG_ERR, QString(
"Setting Ignore%1=false because RecGroup=%1")
97 if (bIgnoreDeleted && (sRecGroup ==
"Deleted"))
99 bIgnoreDeleted =
false;
100 LOG(VB_GENERAL, LOG_ERR, QString(
"Setting Ignore%1=false because RecGroup=%1")
105 sSort, bIgnoreLiveTV, bIgnoreDeleted );
107 QMap< QString, ProgramInfo* >::iterator mit = recMap.begin();
109 for (; mit != recMap.end(); mit = recMap.erase(mit))
119 int nMax = (nCount > 0) ? nCount : progList.
size();
124 QRegularExpression rTitleRegEx
125 { sTitleRegEx, QRegularExpression::CaseInsensitiveOption };
127 for (
auto *pInfo : progList)
129 if (pInfo->IsDeletePending() ||
130 (!sTitleRegEx.isEmpty() && !pInfo->GetTitle().contains(rTitleRegEx)) ||
131 (!sRecGroup.isEmpty() && sRecGroup != pInfo->GetRecordingGroup()) ||
132 (!sStorageGroup.isEmpty() && sStorageGroup != pInfo->GetStorageGroup()) ||
133 (!sCategory.isEmpty() && sCategory != pInfo->GetCategory()))
136 if ((nAvailable < nStartIndex) ||
153 pPrograms->setStartIndex ( nStartIndex );
154 pPrograms->setCount ( nCount );
155 pPrograms->setTotalAvailable( nAvailable );
157 pPrograms->setVersion ( MYTH_BINARY_VERSION );
158 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
170 const QDateTime &sStartTime,
171 const QDateTime &sEndTime,
172 const QString &sTitle,
173 const QString &sSeriesId,
175 const QString &sSort)
177 if (!sStartTime.isNull() && !sStartTime.isValid())
178 throw QString(
"StartTime is invalid");
180 if (!sEndTime.isNull() && !sEndTime.isValid())
181 throw QString(
"EndTime is invalid");
183 const QDateTime& dtStartTime = sStartTime;
184 const QDateTime& dtEndTime = sEndTime;
186 if (!sEndTime.isNull() && dtEndTime < dtStartTime)
187 throw QString(
"EndTime is before StartTime");
197 if (!dtStartTime.isNull())
199 sSQL +=
" AND endtime >= :StartDate ";
200 bindings[
":StartDate"] = dtStartTime;
203 if (!dtEndTime.isNull())
205 sSQL +=
" AND starttime <= :EndDate ";
206 bindings[
":EndDate"] = dtEndTime;
213 clause <<
"recordid = :RecordId";
214 bindings[
":RecordId"] = nRecordId;
217 if (!sTitle.isEmpty())
219 clause <<
"title = :Title";
220 bindings[
":Title"] = sTitle;
223 if (!sSeriesId.isEmpty())
225 clause <<
"seriesid = :SeriesId";
226 bindings[
":SeriesId"] = sSeriesId;
229 if (!clause.isEmpty())
231 sSQL += QString(
" AND (%1) ").arg(clause.join(
" OR "));
234 if (sSort ==
"starttime")
235 sSQL +=
"ORDER BY starttime ";
236 else if (sSort ==
"title")
237 sSQL +=
"ORDER BY title ";
239 sSQL +=
"ORDER BY starttime ";
246 uint nTotalAvailable = (nStartIndex == 0) ? 1 : 0;
248 (
uint)nStartIndex, (
uint)nCount, nTotalAvailable );
256 nCount = (int)progList.
size();
257 int nEndIndex = (int)progList.
size();
259 for(
int n = 0; n < nEndIndex; n++)
270 pPrograms->setStartIndex ( nStartIndex );
271 pPrograms->setCount ( nCount );
272 pPrograms->setTotalAvailable( nTotalAvailable );
274 pPrograms->setVersion ( MYTH_BINARY_VERSION );
275 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
285 int chanid,
const QDateTime &recstarttsRaw)
287 if ((RecordedId <= 0) &&
288 (chanid <= 0 || !recstarttsRaw.isValid()))
289 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
313 throw QString(
"AddRecordedCredits: recordedid %1 does "
314 "not exist.").arg(RecordedId);
317 if (credits ==
nullptr)
318 throw QString(
"AddRecordedCredits: Failed to parse cast from json.");
321 for (
auto & person : *credits)
323 if (!person.InsertDB(query, ri.
GetChanID(),
325 throw QString(
"AddRecordedCredits: Failed to add credit "
326 "%1 to DB").arg(person.toString());
339 QJsonObject root = jsonObj;
340 QJsonObject program = root[
"Program"].toObject();
341 QJsonObject channel = program[
"Channel"].toObject();
342 QJsonObject recording = program[
"Recording"].toObject();
343 QJsonObject cast = program[
"Cast"].toObject();
346 int chanid = channel.value(
"ChanId").toString(
"0").toUInt();
347 QString
hostname = program[
"HostName"].toString(
"");
350 throw QString(
"AddRecordedProgram: chanid %1 does "
351 "not exist.").arg(chanid);
353 pi->m_title = program.value(
"Title").toString(
"");
354 pi->m_subtitle = program.value(
"SubTitle").toString(
"");
355 pi->m_description = program.value(
"Description").toString(
"");
356 pi->m_category = program.value(
"Category").toString(
"");
363 pi->m_airdate = pi->m_originalairdate.year();
364 pi->m_partnumber = program.value(
"PartNumber").toString(
"0").toUInt();
365 pi->m_parttotal = program.value(
"PartTotal").toString(
"0").toUInt();
366 pi->m_syndicatedepisodenumber =
"";
368 (program.value(
"SubPropNames").toString(
""));
370 (program.value(
"AudioPropNames").toString(
""));
372 (program.value(
"VideoPropNames").toString(
""));
373 pi->m_stars = program.value(
"Stars").toString(
"0.0").toFloat();
375 pi->m_seriesId = program.value(
"SeriesId").toString(
"");
376 pi->m_programId = program.value(
"ProgramId").toString(
"");
377 pi->m_inetref = program.value(
"Inetref").toString(
"");
378 pi->m_previouslyshown =
false;
379 pi->m_listingsource = 0;
382 pi->m_season = program.value(
"Season").toString(
"0").toUInt();
383 pi->m_episode = program.value(
"Episode").toString(
"0").toUInt();
384 pi->m_totalepisodes = program.value(
"TotalEpisodes").toString(
"0").toUInt();
386 pi->m_channel = channel.value(
"ChannelName").toString(
"");
388 pi->m_startts = recording.value(
"StartTs").toString(
"");
389 pi->m_endts = recording.value(
"EndTs").toString(
"");
393 pi->m_title_pronounce =
"";
396 pi->m_colorcode =
"";
404 if (!pi->InsertDB(query, chanid,
true))
406 throw QString(
"AddRecordedProgram: "
407 "Failed to add recordedprogram entry.");
412 pi->m_subtitle, pi->m_subtitle,
414 pi->m_season, pi->m_episode,
416 pi->m_syndicatedepisodenumber,
419 channel.value(
"ChanNum").toString(
"0"),
420 channel.value(
"CallSign").toString(
""),
422 recording.value(
"RecGroup").toString(
""),
423 recording.value(
"PlayGroup").toString(
""),
425 recording.value(
"StorageGroup").toString(
""),
433 recording.value(
"Priority").toString(
"0").toInt(),
439 pi->m_originalairdate,
440 program.value(
"Repeat").toString(
"false").toLower() ==
"true",
441 static_cast<RecStatus::Type>(recording.value(
"Status").toString(
"-3").toInt()),
443 recording.value(
"RecordedId").toString(
"0").toInt(),
445 static_cast<RecordingType>(recording.value(
"RecType").toString(
"0").toInt()),
448 channel.value(
"SourceId").toString(
"0").toUInt(),
449 channel.value(
"InputId").toString(
"0").toUInt(),
451 channel.value(
"CommFree").toString(
"false").toLower() ==
"true",
459 recording.value(
"EncoderName").toString(
""));
463 QString
filename = program.value(
"FileName").toString(
"");
465 int idx =
filename.lastIndexOf(
'.');
470 throw QString(
"Failed to create RecordingInfo database entry. "
471 "Non unique starttime?");
494 int chanid,
const QDateTime &recstarttsRaw,
495 bool forceDelete,
bool allowRerecord)
503 int chanid,
const QDateTime &recstarttsRaw,
504 bool forceDelete,
bool allowRerecord)
506 if ((RecordedId <= 0) &&
507 (chanid <= 0 || !recstarttsRaw.isValid()))
508 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
519 QString cmd = QString(
"DELETE_RECORDING %1 %2 %3 %4")
522 forceDelete ?
"FORCE" :
"NO_FORCE",
523 allowRerecord ?
"FORGET" :
"NO_FORGET");
538 int chanid,
const QDateTime &recstarttsRaw)
540 if ((RecordedId <= 0) &&
541 (chanid <= 0 || !recstarttsRaw.isValid()))
542 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
552 QString cmd = QString(
"UNDELETE_RECORDING %1 %2")
571 throw QString(
"RecordedId param is invalid.");
577 QString cmd = QString(
"STOP_RECORDING %1 %2")
585 throw QString(
"RecordedId %1 not found").arg(RecordedId);
595 int chanid,
const QDateTime &recstarttsRaw)
597 if ((RecordedId <= 0) &&
598 (chanid <= 0 || !recstarttsRaw.isValid()))
599 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
623 "RescheduleRecordings");
634 throw QString(
"RecordedId param is invalid.");
639 throw QString(
"RecordedId %1 not found").arg(RecordedId);
652 const QDateTime &recstarttsRaw,
655 if ((RecordedId <= 0) &&
656 (chanid <= 0 || !recstarttsRaw.isValid()))
657 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
681 const QDateTime &recstarttsRaw,
682 const QString &offsettype )
684 if ((RecordedId <= 0) &&
685 (chanid <= 0 || !recstarttsRaw.isValid()))
686 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
699 if (offsettype.toLower() ==
"position"){
705 if (offsettype.toLower() ==
"duration"){
720 const QDateTime &recstarttsRaw,
721 const QString &offsettype,
724 if ((RecordedId <= 0) &&
725 (chanid <= 0 || !recstarttsRaw.isValid()))
726 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
729 throw QString(
"Offset must be >= 0.");
736 uint64_t position = 0;
738 if (offsettype.toLower() ==
"position"){
742 else if (offsettype.toLower() ==
"duration"){
760 const QDateTime &recstarttsRaw,
761 const QString &offsettype )
764 if ((RecordedId <= 0) &&
765 (chanid <= 0 || !recstarttsRaw.isValid()))
766 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
775 if (offsettype.toLower() ==
"position")
777 else if (offsettype.toLower() ==
"duration")
793 const QDateTime &recstarttsRaw,
794 const QString &offsettype )
797 if ((RecordedId <= 0) &&
798 (chanid <= 0 || !recstarttsRaw.isValid()))
799 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
808 if (offsettype.toLower() ==
"position")
810 else if (offsettype.toLower() ==
"duration")
825 const QString &offsettype )
829 throw QString(
"Recorded ID appears invalid.");
835 if (offsettype.toLower() ==
"bytes")
837 else if (offsettype.toLower() ==
"duration")
842 throw QString(
"Type must be 'BYTES' or 'DURATION'.");
860 throw QString(
"Invalid RecordedId %1").arg(RecordedId);
862 QVector<ProgramInfo::MarkupEntry> mapMark;
863 QVector<ProgramInfo::MarkupEntry> mapSeek;
868 for (
const auto& entry : std::as_const(mapMark))
870 DTC::Markup *pMarkup = pMarkupList->AddNewMarkup();
872 pMarkup->setType(typestr);
873 pMarkup->setFrame(entry.frame);
874 if (entry.isDataNull)
875 pMarkup->setData(
"NULL");
877 pMarkup->setData(QString::number(entry.data));
879 for (
const auto& entry : std::as_const(mapSeek))
883 pSeek->setType(typestr);
884 pSeek->setFrame(entry.frame);
885 if (entry.isDataNull)
886 pSeek->setData(
"NULL");
888 pSeek->setData(QString::number(entry.data));
905 throw QString(
"Invalid RecordedId %1").arg(RecordedId);
907 QVector<ProgramInfo::MarkupEntry> mapMark;
908 QVector<ProgramInfo::MarkupEntry> mapSeek;
910 QJsonObject markuplist = jsonObj[
"MarkupList"].toObject();
912 QJsonArray
marks = markuplist[
"Mark"].toArray();
913 for (
const auto & m : std::as_const(
marks))
915 QJsonObject markup = m.toObject();
918 QString typestr = markup.value(
"Type").toString(
"");
920 entry.
frame = markup.value(
"Frame").toString(
"-1").toLongLong();
921 QString data = markup.value(
"Data").toString(
"NULL");
924 entry.
data = data.toLongLong();
926 mapMark.append(entry);
929 QJsonArray seeks = markuplist[
"Seek"].toArray();
930 for (
const auto & m : std::as_const(seeks))
932 QJsonObject markup = m.toObject();
935 QString typestr = markup.value(
"Type").toString(
"");
937 entry.
frame = markup.value(
"Frame").toString(
"-1").toLongLong();
938 QString data = markup.value(
"Data").toString(
"NULL");
941 entry.
data = data.toLongLong();
943 mapSeek.append(entry);
969 nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (
int)infoList.size() ) : 0;
970 nCount = (nCount > 0) ? std::min( nCount, (
int)infoList.size() ) : infoList.size();
971 int nEndIndex = std::min((nStartIndex + nCount), (
int)infoList.size() );
973 for(
int n = nStartIndex; n < nEndIndex; n++)
977 if (pInfo !=
nullptr)
989 pPrograms->setStartIndex ( nStartIndex );
990 pPrograms->setCount ( nCount );
991 pPrograms->setTotalAvailable( infoList.size() );
993 pPrograms->setVersion ( MYTH_BINARY_VERSION );
994 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1009 for (
auto * elink : std::as_const(
gTVList))
1011 if (elink !=
nullptr)
1015 pEncoder->setId ( elink->GetInputID() );
1016 pEncoder->setState ( elink->GetState() );
1017 pEncoder->setLocal ( elink->IsLocal() );
1018 pEncoder->setConnected ( elink->IsConnected() );
1019 pEncoder->setSleepStatus ( elink->GetSleepStatus() );
1022 if (pEncoder->
Local())
1025 pEncoder->setHostName( elink->GetHostName() );
1027 for (
const auto & inputInfo : std::as_const(inputInfoList))
1029 if (inputInfo.m_inputId ==
static_cast<uint>(elink->GetInputID()))
1036 switch ( pEncoder->
State() )
1073 for (
const auto & inputInfo : std::as_const(inputInfoList))
1089 query.
prepare(
"SELECT recgroup FROM recgroups WHERE recgroup <> 'Deleted' "
1090 "ORDER BY recgroup");
1099 while (query.
next())
1100 result << query.
value(0).toString();
1114 query.
prepare(
"SELECT DISTINCT category FROM recorded ORDER BY category");
1116 query.
prepare(
"SELECT DISTINCT category FROM program ORDER BY category");
1125 while (query.
next())
1126 result << query.
value(0).toString();
1159 query.
prepare(
"SELECT filterid, description, newruledefault "
1160 "FROM recordfilter ORDER BY filterid");
1164 while (query.
next())
1167 ruleFilter->setId(query.
value(0).toInt());
1168 ruleFilter->setDescription(QObject::tr(query.
value(1).toString()
1169 .toUtf8().constData()));
1184 QString querystr =
"SELECT DISTINCT title FROM recorded "
1185 "WHERE deletepending = 0";
1187 if (!RecGroup.isEmpty())
1188 querystr +=
" AND recgroup = :RECGROUP";
1190 querystr +=
" AND recgroup != 'Deleted'";
1192 querystr +=
" ORDER BY title";
1196 if (!RecGroup.isEmpty())
1206 while (query.
next())
1207 result << query.
value(0).toString();
1220 QString querystr = QString(
1221 "SELECT title, inetref, count(title) as count "
1222 " FROM recorded AS r "
1223 " JOIN recgroups AS g ON r.recgroupid = g.recgroupid "
1224 " WHERE g.recgroup NOT IN ('Deleted', 'LiveTV') "
1225 " AND r.deletepending = 0 "
1226 " GROUP BY title, inetref "
1238 while (query.
next())
1242 pTitleInfo->setTitle(query.
value(0).toString());
1243 pTitleInfo->setInetref(query.
value(1).toString());
1244 pTitleInfo->setCount(query.
value(2).toInt());
1274 for (
auto it = tmpList.begin(); it < tmpList.end(); ++it)
1276 if ((nRecStatus != 0) &&
1277 ((*it)->GetRecordingStatus() != nRecStatus))
1292 else if (bShowAll &&
1308 nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (
int)recordingList.
size() ) : 0;
1309 nCount = (nCount > 0) ? std::min( nCount, (
int)recordingList.
size() ) : recordingList.
size();
1310 int nEndIndex = std::min((nStartIndex + nCount), (
int)recordingList.
size() );
1312 for(
int n = nStartIndex; n < nEndIndex; n++)
1323 pPrograms->setStartIndex ( nStartIndex );
1324 pPrograms->setCount ( nCount );
1325 pPrograms->setTotalAvailable( recordingList.
size() );
1327 pPrograms->setVersion ( MYTH_BINARY_VERSION );
1328 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1355 for (
auto it = tmpList.begin(); it < tmpList.end(); ++it)
1372 nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (
int)recordingList.
size() ) : 0;
1373 nCount = (nCount > 0) ? std::min( nCount, (
int)recordingList.
size() ) : recordingList.
size();
1374 int nEndIndex = std::min((nStartIndex + nCount), (
int)recordingList.
size() );
1376 for(
int n = nStartIndex; n < nEndIndex; n++)
1387 pPrograms->setStartIndex ( nStartIndex );
1388 pPrograms->setCount ( nCount );
1389 pPrograms->setTotalAvailable( recordingList.
size() );
1391 pPrograms->setVersion ( MYTH_BINARY_VERSION );
1392 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1398 const QString& sTitle,
1399 const QString& sSubtitle,
1400 const QString& sDescription,
1401 const QString& sCategory,
1402 const QDateTime& recstarttsRaw,
1403 const QDateTime& recendtsRaw,
1404 const QString& sSeriesId,
1405 const QString& sProgramId,
1407 const QString& sStation,
1414 const QString& sInetref,
1416 QString sSearchType,
1418 uint nPreferredInput,
1421 const QDateTime& lastrectsRaw,
1426 QString sRecProfile,
1428 QString sStorageGroup,
1434 bool bAutoTranscode,
1435 bool bAutoMetaLookup,
1442 QDateTime recstartts = recstarttsRaw.toUTC();
1443 QDateTime recendts = recendtsRaw.toUTC();
1444 QDateTime lastrects = lastrectsRaw.toUTC();
1448 if (sType.isEmpty())
1451 if (sSearchType.isEmpty())
1452 sSearchType =
"none";
1454 if (sDupMethod.isEmpty())
1455 sDupMethod =
"subtitleanddescription";
1457 if (sDupIn.isEmpty())
1477 if (sRecProfile.isEmpty())
1478 sRecProfile =
"Default";
1480 if (sRecGroup.isEmpty())
1481 sRecGroup =
"Default";
1483 if (sStorageGroup.isEmpty())
1484 sStorageGroup =
"Default";
1486 if (sPlayGroup.isEmpty())
1487 sPlayGroup =
"Default";
1552 const QString& sTitle,
1553 const QString& sSubtitle,
1554 const QString& sDescription,
1555 const QString& sCategory,
1556 const QDateTime& dStartTimeRaw,
1557 const QDateTime& dEndTimeRaw,
1558 const QString& sSeriesId,
1559 const QString& sProgramId,
1561 const QString& sStation,
1567 const QString& sInetref,
1569 QString sSearchType,
1571 uint nPreferredInput,
1578 QString sRecProfile,
1580 QString sStorageGroup,
1586 bool bAutoTranscode,
1587 bool bAutoMetaLookup,
1594 if (nRecordId == 0 )
1595 throw QString(
"Record ID is invalid.");
1602 throw QString(
"Record ID does not exist.");
1604 QDateTime recstartts = dStartTimeRaw.toUTC();
1605 QDateTime recendts = dEndTimeRaw.toUTC();
1608 if (sType.isEmpty())
1611 if (sSearchType.isEmpty())
1612 sSearchType =
"none";
1614 if (sDupMethod.isEmpty())
1615 sDupMethod =
"subtitleanddescription";
1617 if (sDupIn.isEmpty())
1628 if (sRecProfile.isEmpty())
1629 sRecProfile =
"Default";
1631 if (sRecGroup.isEmpty())
1632 sRecGroup =
"Default";
1634 if (sStorageGroup.isEmpty())
1635 sStorageGroup =
"Default";
1637 if (sPlayGroup.isEmpty())
1638 sPlayGroup =
"Default";
1640 if (!sTitle.isEmpty())
1643 if (!sSubtitle.isEmpty())
1646 if(!sDescription.isEmpty())
1649 if (!sCategory.isEmpty())
1652 if (!sSeriesId.isEmpty())
1655 if (!sProgramId.isEmpty())
1660 if (!sStation.isEmpty())
1713 bool bResult = pRule.
Save();
1720 bool bResult =
false;
1722 if (nRecordId == 0 )
1723 throw QString(
"Record ID does not exist.");
1728 bResult = pRule.
Delete();
1736 bool bResult =
true;
1738 if (nChanId <= 0 || !dStartTime.isValid())
1739 throw QString(
"Program does not exist.");
1744 throw QString(
"Program does not exist.");
1765 const QString &Sort,
1769 if (Sort.toLower() ==
"lastrecorded")
1771 else if (Sort.toLower() ==
"nextrecording")
1773 else if (Sort.toLower() ==
"title")
1775 else if (Sort.toLower() ==
"priority")
1777 else if (Sort.toLower() ==
"type")
1791 nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (
int)recList.size() ) : 0;
1792 nCount = (nCount > 0) ? std::min( nCount, (
int)recList.size() ) : recList.size();
1793 int nEndIndex = std::min((nStartIndex + nCount), (
int)recList.size() );
1795 for(
int n = nStartIndex; n < nEndIndex; n++)
1799 if (
info !=
nullptr)
1809 pRecRules->setStartIndex ( nStartIndex );
1810 pRecRules->setCount ( nCount );
1811 pRecRules->setTotalAvailable( recList.size() );
1813 pRecRules->setVersion ( MYTH_BINARY_VERSION );
1814 pRecRules->setProtoVer ( MYTH_PROTO_VERSION );
1816 while (!recList.empty())
1818 delete recList.back();
1826 const QString& sTemplate,
1829 const QDateTime& dStartTimeRaw,
1830 bool bMakeOverride )
1833 QDateTime dStartTime = dStartTimeRaw.toUTC();
1839 throw QString(
"Record ID does not exist.");
1841 else if (!sTemplate.isEmpty())
1844 throw QString(
"Template does not exist.");
1846 else if (nRecordedId > 0)
1851 throw QString(
"Recording does not exist");
1853 else if (nChanId > 0 && dStartTime.isValid())
1860 throw QString(
"Program does not exist.");
1869 throw QString(
"Invalid request.");
1880 bool bResult =
false;
1882 if (nRecordId == 0 )
1883 throw QString(
"Record ID appears invalid.");
1892 bResult = pRule.
Save();
1900 bool bResult =
false;
1902 if (nRecordId == 0 )
1903 throw QString(
"Record ID appears invalid.");
1912 bResult = pRule.
Save();
1931 uint recordedid = 0;
1946 const QDateTime &StartTime)
1958 auto enumType =
static_cast<RecordingType>(recType.toInt(&ok, 10));
1968 auto enumType =
static_cast<RecordingType>(recType.toInt(&ok, 10));
2006 const QString &sJobName,
2009 QDateTime jobstarttsRaw,
2010 QString sRemoteHost,
2018 LOG(VB_GENERAL, LOG_ERR,
"JobName and RecordedId are required.");
2022 if (sRemoteHost.isEmpty())
2035 if ( sAction ==
"Remove")
2039 LOG(VB_GENERAL, LOG_ERR,
"For Remove, a valid JobId is required.");
2050 if ( sAction !=
"Add")
2052 LOG(VB_GENERAL, LOG_ERR, QString(
"Illegal Action name '%1'. Use: Add, "
2053 "or Remove").arg(sAction));
2060 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 hasn't been defined.")
2066 sRemoteHost,
false))
2068 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 hasn't been allowed on host %2.")
2069 .arg(sJobName, sRemoteHost));
2073 if (!jobstarttsRaw.isValid())
2074 jobstarttsRaw = QDateTime::currentDateTime();
2079 if (sJobArgs.isNull())
2086 QString(
"Dvr/ManageJobQueue"),
2090 jobstarttsRaw.toUTC());
2094 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 job wasn't queued because of a "
2095 "database error or because it was "
2096 "already running/stopping etc.")
static QStringList getRecordingsGroups(void)
static uint GetRecgroupID(const QString &recGroup)
Temporary helper during transition from string to ID.
QString DupMethodToDescription(const QString &DupMethod) override
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
bool LoadByProgram(const ProgramInfo *proginfo)
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool SetRecordedMarkup(int RecordedId, const QJsonObject &json) override
void FillProgramInfo(DTC::Program *pProgram, ProgramInfo *pInfo, bool bIncChannel, bool bDetails, bool bIncCast)
DTC::RecRule * GetRecordSchedule(uint RecordId, const QString &Template, int nRecordedId, int ChanId, const QDateTime &dStartTimeRaw, bool MakeOverride) override
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
DTC::MarkupList * GetRecordedMarkup(int RecordedId) override
static bool QueryRecordedIdForKey(int &recordedid, uint chanid, const QDateTime &recstartts)
void FillRecRuleInfo(DTC::RecRule *pRecRule, RecordingRule *pRule)
void ApplyNeverRecord(void)
Set this program to never be recorded by inserting 'history' for it into the database with a status o...
DTC::RecRuleFilterList * GetRecRuleFilterList() override
void SaveBookmark(uint64_t frame)
Clears any existing bookmark in DB and if frame is greater than 0 sets a new bookmark.
void SetRecordingStatus(RecStatus::Type status)
QString RecStatusToDescription(int RecStatus, int RecType, const QDateTime &StartTime) override
MythScheduler * GetScheduler(void)
int AddRecordedProgram(const QJsonObject &json) override
ProgramInfo * LoadProgramFromProgram(const uint chanid, const QDateTime &starttime)
bool Save(bool sendSig=true)
static bool QueueJob(int jobType, uint chanid, const QDateTime &recstartts, const QString &args="", const QString &comment="", QString host="", int flags=0, int status=JOB_QUEUED, QDateTime schedruntime=QDateTime())
void ApplyRecordStateChange(RecordingType newstate, bool save=true)
Sets RecordingType of "record", creating "record" if it does not exist.
RecSearchType searchTypeFromString(const QString &type)
QStringList GetProgramCategories(bool OnlyRecorded) override
RecordingDupInType dupInFromString(const QString &type)
static void GetAllScheduled(QStringList &strList, SchedSortColumn sortBy=kSortTitle, bool ascending=true)
Returns all scheduled programs serialized into a QStringList.
Holds information on a TV Program one might wish to record.
void ForgetHistory(void)
Forget the recording of a program so it will be recorded again.
void QueryMarkup(QVector< MarkupEntry > &mapMark, QVector< MarkupEntry > &mapSeek) const
uint GetRecordingID(void) const
bool AllowReRecord(int RecordedId) override
DTC::TitleInfoList * GetTitleInfoList() override
This class is used as a container for messages.
DTC::ProgramList * GetOldRecordedList(bool Descending, int StartIndex, int Count, const QDateTime &StartTime, const QDateTime &EndTime, const QString &Title, const QString &SeriesId, int RecordId, const QString &Sort) override
static QMap< QString, bool > QueryJobsRunning(int type)
bool QueryPositionKeyFrame(uint64_t *keyframe, uint64_t position, bool backwards) const
QVariant value(int i) const
Internal representation of a recording rule, mirrors the record table.
static bool SafeDeleteJob(int jobID, int jobType, int chanid, const QDateTime &recstartts)
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void SaveCommFlagged(CommFlagStatus flag)
Set "commflagged" field in "recorded" table to "flag".
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
bool QueryKeyFrameDuration(uint64_t *duration, uint64_t keyframe, bool backwards) const
DTC::InputList * GetInputList() override
bool LoadFromRecorded(ProgramList &destination, bool possiblyInProgressRecordingsOnly, const QMap< QString, uint32_t > &inUseMap, const QMap< QString, bool > &isJobRunning, const QMap< QString, ProgramInfo * > &recMap, int sort, const QString &sortBy, bool ignoreLiveTV, bool ignoreDeleted)
void GetAllExpiring(QStringList &strList)
Gets the full list of programs that can expire in expiration order.
DTC::CutList * GetRecordedSeek(int RecordedId, const QString &OffsetType) override
RecordingDupInType m_dupIn
int RecordedIdForPathname(const QString &pathname) override
bool m_isInactive
Recording rule is enabled?
QString RecTypeToString(const QString &RecType) override
DTC::ProgramList * GetExpiringList(int StartIndex, int Count) override
QString DupMethodToString(const QString &DupMethod) override
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
DTC::RecRuleList * GetRecordScheduleList(int StartIndex, int Count, const QString &Sort, bool Descending) override
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
bool IsWatched(void) const
std::vector< DBPerson > DBCredits
static QString toString(RecStatus::Type recstatus, uint id)
Converts "recstatus" into a short (unreadable) string.
static bool InJobRunWindow(QDateTime jobstarttsRaw)
bool IsPreserved(void) const
ProgramInfo::CategoryType string_to_myth_category_type(const QString &category_type)
uint64_t QueryBookmark(void) const
Gets any bookmark position in database, unless the ignore bookmark flag is set.
static QStringList GetNames(void)
virtual QMap< QString, ProgramInfo * > GetRecording(void) const =0
QString RecStatusToString(int RecStatus) override
bool Load(bool asTemplate=false)
Load a single rule from the recorded table.
bool StopRecording(int RecordedId) override
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
static bool QueryRecordedIdFromPathname(const QString &pathname, uint &recordedid)
bool IsValid(QString &msg) const
DTC::CutList * GetRecordedCutList(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, const QString &OffsetType) override
DTC::EncoderList * GetEncoderList() override
static QString toDescription(Type recstatus, RecordingType rectype, const QDateTime &recstartts)
Converts "recstatus" into a long human readable description.
bool RescheduleRecordings(void) override
void FillCutList(DTC::CutList *pCutList, RecordingInfo *rInfo, int marktype)
DTC::Program * GetRecorded(int RecordedId, int ChanId, const QDateTime &recstarttsRaw) override
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
bool UnDeleteRecording(int RecordedId, int ChanId, const QDateTime &recstarttsRaw) override
static void DBError(const QString &where, const MSqlQuery &query)
QTime m_findtime
Time for timeslot rules.
RecordingDupMethodType dupMethodFromString(const QString &type)
MarkTypes markTypeFromString(const QString &str)
RecSearchType m_searchType
std::vector< ProgramInfo * > pginfolist_t
RecordingType recTypeFromString(const QString &type)
void FillSeek(DTC::CutList *pCutList, RecordingInfo *rInfo, MarkTypes marktype)
bool RemoveRecorded(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, bool ForceDelete, bool AllowRerecord) override
bool UpdateRecordSchedule(uint RecordId, const QString &Title, const QString &Subtitle, const QString &Description, const QString &Category, const QDateTime &dStartTimeRaw, const QDateTime &dEndTimeRaw, const QString &SeriesId, const QString &ProgramId, int ChanId, const QString &Station, int FindDay, QTime FindTime, bool Inactive, uint Season, uint Episode, const QString &Inetref, QString Type, QString SearchType, int RecPriority, uint PreferredInput, int StartOffset, int EndOffset, QString DupMethod, QString DupIn, bool NewEpisOnly, uint Filter, QString RecProfile, QString RecGroup, QString StorageGroup, QString PlayGroup, bool AutoExpire, int MaxEpisodes, bool MaxNewest, bool AutoCommflag, bool AutoTranscode, bool AutoMetaLookup, bool AutoUserJob1, bool AutoUserJob2, bool AutoUserJob3, bool AutoUserJob4, int Transcoder) override
RecordingDupInType dupInFromStringAndBool(const QString &type, bool newEpisodesOnly)
bool UpdateRecordedWatchedStatus(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, bool Watched) override
QStringList GetPlayGroupList() override
QList< QString > m_parsedParams
@ kState_WatchingLiveTV
Watching LiveTV is the state for when we are watching a recording and the user has control over the c...
int m_findday
Day of the week for once per week etc.
bool AddRecordedCredits(int RecordedId, const QJsonObject &json) override
void ReactivateRecording(void)
Asks the scheduler to restart this recording if possible.
static QReadWriteLock s_inputsLock
void ProgramFlagsFromNames(const QString &names)
QMap< int, EncoderLink * > gTVList
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
bool DeleteRecording(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, bool ForceDelete, bool AllowRerecord) override
QString toDescription(RecordingType rectype)
Converts "rectype" into a human readable description.
int RecordedIdForKey(int ChanId, const QDateTime &recstarttsRaw) override
static uint AudioPropertiesFromNames(const QString &names)
void SaveAutoExpire(AutoExpireType autoExpire, bool updateDelete=false)
Set "autoexpire" field in "recorded" table to "autoExpire".
@ kState_WatchingRecording
Watching Recording is the state for when we are watching an in progress recording,...
static uint SubtitleTypesFromNames(const QString &names)
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
QStringList GetRecStorageGroupList() override
bool AddDontRecordSchedule(int ChanId, const QDateTime &StartTime, bool NeverRecord) override
DTC::ProgramList * GetUpcomingList(int StartIndex, int Count, bool ShowAll, int RecordId, int RecStatus) override
AutoDeleteDeque< ProgramInfo * > ProgramList
QString RecTypeToDescription(const QString &RecType) override
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Holds information on recordings and videos.
bool LoadTemplate(const QString &title, const QString &category="Default", const QString &categoryType="Default")
bool DisableRecordSchedule(uint RecordId) override
int m_recordID
Unique Recording Rule ID.
bool QueryKeyFramePosition(uint64_t *position, uint64_t keyframe, bool backwards) const
static int GetJobTypeFromName(const QString &name)
uint AddRecordSchedule(const QString &Title, const QString &Subtitle, const QString &Description, const QString &Category, const QDateTime &recstarttsRaw, const QDateTime &recendtsRaw, const QString &SeriesId, const QString &ProgramId, int ChanId, const QString &Station, int FindDay, QTime FindTime, int ParentId, bool Inactive, uint Season, uint Episode, const QString &Inetref, QString Type, QString SearchType, int RecPriority, uint PreferredInput, int StartOffset, int EndOffset, const QDateTime &lastrectsRaw, QString DupMethod, QString DupIn, bool NewEpisOnly, uint Filter, QString RecProfile, QString RecGroup, QString StorageGroup, QString PlayGroup, bool AutoExpire, int MaxEpisodes, bool MaxNewest, bool AutoCommflag, bool AutoTranscode, bool AutoMetaLookup, bool AutoUserJob1, bool AutoUserJob2, bool AutoUserJob3, bool AutoUserJob4, int Transcoder) override
bool InsertRecording(const QString &ext, bool force_match=false)
RecordingDupMethodType m_dupMethod
void FillCommBreak(DTC::CutList *pCutList, RecordingInfo *rInfo, int marktype)
bool IsCommercialFlagged(void) const
static int GetJobID(int jobType, uint chanid, const QDateTime &recstartts)
bool ReactivateRecording(int RecordedId, int ChanId, const QDateTime &recstarttsRaw) override
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool RemoveRecordSchedule(uint RecordId) override
static QMap< QString, uint32_t > QueryInUseMap(void)
void SaveWatched(bool watchedFlag)
Set "watched" field in recorded/videometadata to "watchedFlag".
std::deque< RecordingInfo * > RecList
bool IsAutoExpirable(void) const
QStringList GetTitleList(const QString &RecGroup) override
static const std::array< const mark, 16 > marks
void SendUpdateEvent(void) const
Sends event out that the ProgramInfo should be reloaded.
void SavePreserve(bool preserveEpisode)
Set "preserve" field in "recorded" table to "preserveEpisode".
QStringList GetRecGroupList() override
bool SetSavedBookmark(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, const QString &OffsetType, long Offset) override
QString DupInToDescription(const QString &DupIn) override
int CreateRecordingGroup(const QString &groupName)
@ kState_RecordingOnly
Recording Only is a TVRec only state for when we are recording a program, but there is no one current...
bool LoadFromOldRecorded(ProgramList &destination, const QString &sql, const MSqlBindings &bindings)
bool Delete(bool sendSig=true)
QString DupInToString(const QString &DupIn) override
QString GetHostName(void)
bool GetAllPending(RecList &retList, int recRuleId=0) const
int ManageJobQueue(const QString &Action, const QString &JobName, int JobId, int RecordedId, QDateTime jobstarttsRaw, QString RemoteHost, QString JobArgs) override
void SaveMarkup(const QVector< MarkupEntry > &mapMark, const QVector< MarkupEntry > &mapSeek) const
bool GetBoolSettingOnHost(const QString &key, const QString &host, bool defaultval=false)
DTC::ProgramList * GetConflictList(int StartIndex, int Count, int RecordId) override
static QString GetChanNum(int chan_id)
Returns the channel-number string of the given channel.
DTC::CutList * GetRecordedCommBreak(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, const QString &OffsetType) override
static QList< InputInfo > GetAllInputInfo(bool virtTuners)
bool QueryDurationKeyFrame(uint64_t *keyframe, uint64_t duration, bool backwards) const
bool EnableRecordSchedule(uint RecordId) override
DTC::ProgramList * GetRecordedList(bool Descending, int StartIndex, int Count, const QString &TitleRegEx, const QString &RecGroup, const QString &StorageGroup, const QString &Category, const QString &Sort, bool IgnoreLiveTV, bool IgnoreDeleted) override
static void RescheduleMatch(uint recordid, uint sourceid, uint mplexid, const QDateTime &maxstarttime, const QString &why)
void dispatch(const MythEvent &event)
long GetSavedBookmark(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, const QString &OffsetType) override
bool m_autoMetadataLookup
bool HasPathname(void) const
static uint VideoPropertiesFromNames(const QString &names)
DBCredits * jsonCastToCredits(const QJsonObject &cast)
QString GetSetting(const QString &key, const QString &defaultval="")
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
void FillInputInfo(DTC::Input *input, const InputInfo &inputInfo)