29#include <QJsonDocument>
37#include "libmythbase/mythversion.h"
62 qRegisterMetaType<V2ProgramList*>(
"V2ProgramList");
63 qRegisterMetaType<V2Program*>(
"V2Program");
64 qRegisterMetaType<V2CutList*>(
"V2CutList");
65 qRegisterMetaType<V2Cutting*>(
"V2Cutting");
66 qRegisterMetaType<V2MarkupList*>(
"V2MarkupList");
67 qRegisterMetaType<V2Markup*>(
"V2Markup");
68 qRegisterMetaType<V2EncoderList*>(
"V2EncoderList");
69 qRegisterMetaType<V2Encoder*>(
"V2Encoder");
70 qRegisterMetaType<V2InputList*>(
"V2InputList");
71 qRegisterMetaType<V2Input*>(
"V2Input");
72 qRegisterMetaType<V2RecRuleFilterList*>(
"V2RecRuleFilterList");
73 qRegisterMetaType<V2RecRuleFilter*>(
"V2RecRuleFilter");
74 qRegisterMetaType<V2TitleInfoList*>(
"V2TitleInfoList");
75 qRegisterMetaType<V2TitleInfo*>(
"V2TitleInfo");
76 qRegisterMetaType<V2RecRule*>(
"V2RecRule");
77 qRegisterMetaType<V2RecRuleList*>(
"V2RecRuleList");
78 qRegisterMetaType<V2ChannelInfo*>(
"V2ChannelInfo");
79 qRegisterMetaType<V2RecordingInfo*>(
"V2RecordingInfo");
80 qRegisterMetaType<V2ArtworkInfoList*>(
"V2ArtworkInfoList");
81 qRegisterMetaType<V2ArtworkInfo*>(
"V2ArtworkInfo");
82 qRegisterMetaType<V2CastMemberList*>(
"V2CastMemberList");
83 qRegisterMetaType<V2CastMember*>(
"V2CastMember");
84 qRegisterMetaType<V2PlayGroup*>(
"V2PlayGroup");
85 qRegisterMetaType<V2PowerPriority*>(
"V2PowerPriority");
86 qRegisterMetaType<V2PowerPriorityList*>(
"V2PowerPriorityList");
108 nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (
int)infoList.size() ) : 0;
109 nCount = (nCount > 0) ? std::min( nCount, (
int)infoList.size() ) : infoList.size();
110 int nEndIndex = std::min((nStartIndex + nCount), (
int)infoList.size() );
112 for(
int n = nStartIndex; n < nEndIndex; n++)
116 if (pInfo !=
nullptr)
118 V2Program *pProgram = pPrograms->AddNewProgram();
128 pPrograms->setStartIndex ( nStartIndex );
129 pPrograms->setCount ( nCount );
130 pPrograms->setTotalAvailable( infoList.size() );
132 pPrograms->setVersion ( MYTH_BINARY_VERSION );
133 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
141 const QString &sTitleRegEx,
142 const QString &sRecGroup,
143 const QString &sStorageGroup,
144 const QString &sCategory,
145 const QString &sSort,
168 bIncRecording =
true;
170 QMap< QString, ProgramInfo* > recMap;
184 if (bIgnoreLiveTV && (sRecGroup ==
"LiveTV"))
186 bIgnoreLiveTV =
false;
187 LOG(VB_GENERAL, LOG_ERR, QString(
"Setting Ignore%1=false because RecGroup=%1")
191 if (bIgnoreDeleted && (sRecGroup ==
"Deleted"))
193 bIgnoreDeleted =
false;
194 LOG(VB_GENERAL, LOG_ERR, QString(
"Setting Ignore%1=false because RecGroup=%1")
199 sSort, bIgnoreLiveTV, bIgnoreDeleted );
201 QMap< QString, ProgramInfo* >::iterator mit = recMap.begin();
203 for (; mit != recMap.end(); mit = recMap.erase(mit))
214 int nMax = (nCount > 0) ? nCount : progList.
size();
219 QRegularExpression rTitleRegEx
220 { sTitleRegEx, QRegularExpression::CaseInsensitiveOption };
222 for (
auto *pInfo : progList)
224 if (pInfo->IsDeletePending() ||
225 (!sTitleRegEx.isEmpty() && !pInfo->GetTitle().contains(rTitleRegEx)) ||
226 (!sRecGroup.isEmpty() && sRecGroup != pInfo->GetRecordingGroup()) ||
227 (!sStorageGroup.isEmpty() && sStorageGroup != pInfo->GetStorageGroup()) ||
228 (!sCategory.isEmpty() && sCategory != pInfo->GetCategory()))
231 if ((nAvailable < nStartIndex) ||
241 V2Program *pProgram = pPrograms->AddNewProgram();
242 V2FillProgramInfo( pProgram, pInfo, bIncChannel, bDetails, bIncCast, bIncArtWork, bIncRecording );
247 pPrograms->setStartIndex ( nStartIndex );
248 pPrograms->setCount ( nCount );
249 pPrograms->setTotalAvailable( nAvailable );
251 pPrograms->setVersion ( MYTH_BINARY_VERSION );
252 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
265 const QDateTime &sStartTime,
266 const QDateTime &sEndTime,
267 const QString &sTitle,
268 const QString &TitleRegEx,
269 const QString &SubtitleRegEx,
270 const QString &sSeriesId,
272 const QString &sSort)
274 if (!sStartTime.isNull() && !sStartTime.isValid())
275 throw QString(
"StartTime is invalid");
277 if (!sEndTime.isNull() && !sEndTime.isValid())
278 throw QString(
"EndTime is invalid");
280 const QDateTime& dtStartTime = sStartTime;
281 const QDateTime& dtEndTime = sEndTime;
283 if (!sEndTime.isNull() && dtEndTime < dtStartTime)
284 throw QString(
"EndTime is before StartTime");
294 if (!dtStartTime.isNull())
296 sSQL +=
" AND endtime >= :StartDate ";
297 bindings[
":StartDate"] = dtStartTime;
300 if (!dtEndTime.isNull())
302 sSQL +=
" AND starttime <= :EndDate ";
303 bindings[
":EndDate"] = dtEndTime;
310 clause <<
"recordid = :RecordId";
311 bindings[
":RecordId"] = nRecordId;
314 if (!sTitle.isEmpty())
316 clause <<
"title = :Title";
317 bindings[
":Title"] = sTitle;
320 if (!TitleRegEx.isEmpty())
322 clause <<
"title REGEXP :TitleRegEx";
323 bindings[
":TitleRegEx"] = TitleRegEx;
326 if (!SubtitleRegEx.isEmpty())
328 clause <<
"subtitle REGEXP :SubtitleRegEx";
329 bindings[
":SubtitleRegEx"] = SubtitleRegEx;
332 if (!sSeriesId.isEmpty())
334 clause <<
"seriesid = :SeriesId";
335 bindings[
":SeriesId"] = sSeriesId;
338 if (!clause.isEmpty())
340 sSQL += QString(
" AND (%1) ").arg(clause.join(
" AND "));
343 QStringList sortByFields;
344 sortByFields <<
"starttime" <<
"title" <<
"subtitle" <<
"season" <<
"episode" <<
"category"
345 <<
"channum" <<
"rectype" <<
"recstatus" <<
"duration" ;
346 QStringList fields = sSort.split(
",");
348 fields <<
"starttime";
349 sSQL +=
" ORDER BY ";
351 for (
const QString& oneField : std::as_const(fields))
353 QString field = oneField.simplified().toLower();
356 if (sortByFields.contains(field))
362 if (field ==
"channum")
365 field =
"channum*1000-ifnull(regexp_substr(channum,'-.*'),0)";
367 else if (field ==
"duration")
369 field =
"timestampdiff(second,starttime,endtime)";
371 else if (field ==
"title")
374 QString prefixes = sh->getPrefixes();
375 field =
"REGEXP_REPLACE(title,'" + prefixes +
"','')";
377 else if (field ==
"subtitle")
380 QString prefixes = sh->getPrefixes();
381 field =
"REGEXP_REPLACE(subtitle,'" + prefixes +
"','')";
391 LOG(VB_GENERAL, LOG_WARNING, QString(
"V2Dvr::GetOldRecordedList() got an unknown sort field '%1' - ignoring").arg(oneField));
395 uint nTotalAvailable = (nStartIndex == 0) ? 1 : 0;
397 (
uint)nStartIndex, (
uint)nCount, nTotalAvailable );
405 nCount = (int)progList.
size();
406 int nEndIndex = (int)progList.
size();
408 for(
int n = 0; n < nEndIndex; n++)
412 V2Program *pProgram = pPrograms->AddNewProgram();
419 pPrograms->setStartIndex ( nStartIndex );
420 pPrograms->setCount ( nCount );
421 pPrograms->setTotalAvailable( nTotalAvailable );
423 pPrograms->setVersion ( MYTH_BINARY_VERSION );
424 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
430 const QDateTime &StartTime,
434 throw QString(
"Channel ID and StartTime appears invalid.");
435 QString sql(
"DELETE FROM oldrecorded "
436 " WHERE chanid = :ChanId AND starttime = :StartTime" );
440 query.
bindValue(
":StartTime", StartTime);
456 const QDateTime &StartTime,
461 throw QString(
"Channel ID and StartTime appears invalid.");
463 throw QString(
"Error: Nothing to change.");
464 QString sql(
"UPDATE oldrecorded "
465 " SET Duplicate = :Duplicate "
466 " WHERE chanid = :ChanId AND starttime = :StartTime" );
469 query.
bindValue(
":Duplicate", Duplicate);
471 query.
bindValue(
":StartTime", StartTime);
489 int chanid,
const QDateTime &StartTime)
491 if ((RecordedId <= 0) &&
492 (chanid <= 0 || !StartTime.isValid()))
493 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
514 QJsonDocument jsonDoc = QJsonDocument::fromJson(Cast.toUtf8());
518 throw QString(
"AddRecordedCredits: recordedid %1 does "
519 "not exist.").arg(RecordedId);
522 if (credits ==
nullptr)
523 throw QString(
"AddRecordedCredits: Failed to parse cast from json.");
526 for (
auto & person : *credits)
528 if (!person.InsertDB(query, ri.
GetChanID(),
530 throw QString(
"AddRecordedCredits: Failed to add credit "
531 "%1 to DB").arg(person.toString());
543 QJsonDocument doc = QJsonDocument::fromJson(Program.toUtf8());
544 QJsonObject program = doc.object();
545 QJsonObject channel = program[
"Channel"].toObject();
546 QJsonObject recording = program[
"Recording"].toObject();
547 QJsonObject cast = program[
"Cast"].toObject();
550 int chanid = channel.value(
"ChanId").toVariant().toString().toUInt();
552 QString
hostname = program[
"HostName"].toString(
"");
555 throw QString(
"AddRecordedProgram: chanid %1 does "
556 "not exist.").arg(chanid);
558 pi->m_title = program.value(
"Title").toString(
"");
559 pi->m_subtitle = program.value(
"SubTitle").toString(
"");
560 pi->m_description = program.value(
"Description").toString(
"");
561 pi->m_category = program.value(
"Category").toString(
"");
568 pi->m_airdate = pi->m_originalairdate.year();
569 pi->m_partnumber = program.value(
"PartNumber").toString(
"0").toUInt();
570 pi->m_parttotal = program.value(
"PartTotal").toString(
"0").toUInt();
571 pi->m_syndicatedepisodenumber =
"";
573 (program.value(
"SubPropNames").toString(
""));
575 (program.value(
"AudioPropNames").toString(
""));
577 (program.value(
"VideoPropNames").toString(
""));
578 pi->m_stars = program.value(
"Stars").toVariant().toString().toFloat();
580 pi->m_seriesId = program.value(
"SeriesId").toString(
"");
581 pi->m_programId = program.value(
"ProgramId").toString(
"");
582 pi->m_inetref = program.value(
"Inetref").toString(
"");
583 pi->m_previouslyshown =
false;
584 pi->m_listingsource = 0;
587 pi->m_season = program.value(
"Season").toVariant()
588 .toString().toUInt();
589 pi->m_episode = program.value(
"Episode").toVariant()
590 .toString().toUInt();
591 pi->m_totalepisodes = program.value(
"TotalEpisodes").toVariant()
592 .toString().toUInt();
594 pi->m_channel = channel.value(
"ChannelName").toString(
"");
596 pi->m_startts = recording.value(
"StartTs").toString(
"");
597 pi->m_endts = recording.value(
"EndTs").toString(
"");
601 pi->m_title_pronounce =
"";
604 pi->m_colorcode =
"";
612 if (!pi->InsertDB(query, chanid,
true))
614 throw QString(
"AddRecordedProgram: "
615 "Failed to add recordedprogram entry.");
620 pi->m_subtitle, pi->m_subtitle,
622 pi->m_season, pi->m_episode,
624 pi->m_syndicatedepisodenumber,
627 channel.value(
"ChanNum").toString(
"0"),
628 channel.value(
"CallSign").toString(
""),
630 recording.value(
"RecGroup").toString(
""),
631 recording.value(
"PlayGroup").toString(
""),
633 recording.value(
"StorageGroup").toString(
""),
641 recording.value(
"Priority").toString(
"0").toInt(),
647 pi->m_originalairdate,
648 program.value(
"Repeat").toString(
"false").toLower() ==
"true",
651 recording.value(
"RecordedId").toString(
"0").toInt(),
653 static_cast<RecordingType>(recording.value(
"RecType").toInt()),
656 channel.value(
"SourceId").toVariant().toString().toUInt(),
657 channel.value(
"InputId").toVariant().toString().toUInt(),
659 channel.value(
"CommFree").toBool(),
667 recording.value(
"EncoderName").toString(
""));
671 QString
filename = program.value(
"FileName").toString(
"");
673 int idx =
filename.lastIndexOf(
'.');
678 throw QString(
"Failed to create RecordingInfo database entry. "
679 "Non unique starttime?");
702 int chanid,
const QDateTime &StartTime,
703 bool forceDelete,
bool allowRerecord)
711 int chanid,
const QDateTime &StartTime,
712 bool forceDelete,
bool allowRerecord)
714 if ((RecordedId <= 0) &&
715 (chanid <= 0 || !StartTime.isValid()))
716 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
727 QString cmd = QString(
"DELETE_RECORDING %1 %2 %3 %4")
730 forceDelete ?
"FORCE" :
"NO_FORCE",
731 allowRerecord ?
"FORGET" :
"NO_FORGET");
746 int chanid,
const QDateTime &StartTime)
748 if ((RecordedId <= 0) &&
749 (chanid <= 0 || !StartTime.isValid()))
750 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
760 QString cmd = QString(
"UNDELETE_RECORDING %1 %2")
779 throw QString(
"RecordedId param is invalid.");
785 QString cmd = QString(
"STOP_RECORDING %1 %2")
793 throw QString(
"RecordedId %1 not found").arg(RecordedId);
808 int ChanId,
const QDateTime &StartTime,
816 else if (ChanId > 0 && StartTime.isValid())
820 else if (RecordId > 0)
824 query.
prepare(
"SELECT recordedid FROM recorded "
825 " WHERE recordid = :RECORDID "
826 " ORDER BY starttime DESC LIMIT 1");
835 recId = query.
value(0).toInt();
842 throw QString(
"Recorded ID or Channel ID and StartTime or RecordId are invalid.");
860 "RescheduleRecordings");
872 if (ChanId > 0 || StartTime.isValid())
873 throw QString(
"ERROR RecordedId param cannot be used with ChanId or StartTime.");
877 if (!StartTime.isValid())
878 throw QString(
"ERROR ChanId param requires a valid StartTime.");
882 throw QString(
"ERROR RecordedId or (ChanId and StartTime) required.");
889 throw QString(
"ERROR RecordedId %1 not found").arg(RecordedId);
895 if (progInfo ==
nullptr)
896 throw QString(
"ERROR Guide data for Chanid %1 at StartTime %2 not found")
897 .arg(ChanId).arg(StartTime.toString());
911 const QDateTime &StartTime,
916 if ((RecordedId <= 0) &&
917 (chanid <= 0 || !StartTime.isValid()))
918 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
942 const QDateTime &StartTime,
943 const QString &offsettype )
945 if ((RecordedId <= 0) &&
946 (chanid <= 0 || !StartTime.isValid()))
947 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
960 if (offsettype.toLower() ==
"position"){
966 if (offsettype.toLower() ==
"duration"){
984 const QDateTime &StartTime,
985 const QString &offsettype )
987 if (RecordedId == -1)
990 if ((RecordedId <= 0) &&
991 (chanid <= 0 || !StartTime.isValid()))
992 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1005 if (offsettype.toLower() ==
"position"){
1011 if (offsettype.toLower() ==
"duration"){
1026 const QDateTime &StartTime,
1027 const QString &offsettype,
1032 if ((RecordedId <= 0) &&
1033 (chanid <= 0 || !StartTime.isValid()))
1034 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1037 throw QString(
"Offset must be >= 0.");
1044 uint64_t position = 0;
1046 if (offsettype.toLower() ==
"position"){
1050 else if (offsettype.toLower() ==
"duration"){
1070 const QDateTime &StartTime,
1071 const QString &offsettype,
1076 if ((RecordedId <= 0) &&
1077 (chanid <= 0 || !StartTime.isValid()))
1078 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1081 throw QString(
"Offset must be >= 0.");
1088 uint64_t position = 0;
1090 if (offsettype.toLower() ==
"position"){
1094 else if (offsettype.toLower() ==
"duration"){
1108 const QDateTime &StartTime,
1109 const QString &offsettype,
1113 if ((RecordedId <= 0) &&
1114 (chanid <= 0 || !StartTime.isValid()))
1115 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1124 if (offsettype.toLower() ==
"position")
1126 else if (offsettype.toLower() ==
"duration")
1142 const QDateTime &StartTime,
1143 const QString &offsettype,
1147 if ((RecordedId <= 0) &&
1148 (chanid <= 0 || !StartTime.isValid()))
1149 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1158 if (offsettype.toLower() ==
"position")
1160 else if (offsettype.toLower() ==
"duration")
1175 const QString &offsettype )
1178 if (RecordedId <= 0)
1179 throw QString(
"Recorded ID appears invalid.");
1185 if (offsettype.toLower() ==
"bytes")
1189 else if (offsettype.toLower() ==
"duration")
1196 throw QString(
"Type must be 'BYTES' or 'DURATION'.");
1214 throw QString(
"Invalid RecordedId %1").arg(RecordedId);
1216 QVector<ProgramInfo::MarkupEntry> mapMark;
1217 QVector<ProgramInfo::MarkupEntry> mapSeek;
1222 for (
const auto& entry : std::as_const(mapMark))
1224 V2Markup *pMarkup = pMarkupList->AddNewMarkup();
1226 pMarkup->setType(typestr);
1227 pMarkup->setFrame(entry.frame);
1228 if (entry.isDataNull)
1229 pMarkup->setData(
"NULL");
1231 pMarkup->setData(QString::number(entry.data));
1233 for (
const auto& entry : std::as_const(mapSeek))
1235 V2Markup *pSeek = pMarkupList->AddNewSeek();
1237 pSeek->setType(typestr);
1238 pSeek->setFrame(entry.frame);
1239 if (entry.isDataNull)
1240 pSeek->setData(
"NULL");
1242 pSeek->setData(QString::number(entry.data));
1259 throw QString(
"Invalid RecordedId %1").arg(RecordedId);
1261 QVector<ProgramInfo::MarkupEntry> mapMark;
1262 QVector<ProgramInfo::MarkupEntry> mapSeek;
1264 QJsonDocument doc = QJsonDocument::fromJson(MarkupList.toUtf8());
1265 QJsonObject markuplist = doc.object();
1267 QJsonArray marks = markuplist[
"Mark"].toArray();
1268 for (
const auto & m : std::as_const(marks))
1270 QJsonObject markup = m.toObject();
1273 QString typestr = markup.value(
"Type").toString(
"");
1275 entry.
frame = markup.value(
"Frame").toVariant()
1276 .toString().toLongLong();
1277 QString data = markup.value(
"Data").toString(
"NULL");
1280 entry.
data = data.toLongLong();
1282 mapMark.append(entry);
1285 QJsonArray seeks = markuplist[
"Seek"].toArray();
1286 for (
const auto & m : std::as_const(seeks))
1288 QJsonObject markup = m.toObject();
1291 QString typestr = markup.value(
"Type").toString(
"");
1293 entry.
frame = markup.value(
"Frame").toVariant().toString().toLongLong();
1294 QString data = markup.value(
"Data").toString(
"NULL");
1297 entry.
data = data.toLongLong();
1299 mapSeek.append(entry);
1327 for (
const auto & inputInfo : std::as_const(inputInfoList))
1329 V2Input *input = pList->AddNewInput();
1343 if (UsedBy.compare(
"recorded",Qt::CaseInsensitive) == 0)
1344 query.
prepare(
"SELECT DISTINCT recgroup FROM recorded "
1345 "ORDER BY recgroup");
1346 else if (UsedBy.compare(
"schedule",Qt::CaseInsensitive) == 0)
1347 query.
prepare(
"SELECT DISTINCT recgroup FROM record "
1348 "ORDER BY recgroup");
1350 query.
prepare(
"SELECT recgroup FROM recgroups WHERE recgroup <> 'Deleted' "
1351 "ORDER BY recgroup");
1360 while (query.
next())
1361 result << query.
value(0).toString();
1375 query.
prepare(
"SELECT DISTINCT category FROM recorded ORDER BY category");
1377 query.
prepare(
"SELECT DISTINCT category FROM program ORDER BY category");
1386 while (query.
next())
1387 result << query.
value(0).toString();
1416 query.
prepare(
"SELECT name, titlematch, skipahead, skipback, timestretch, jump "
1417 "FROM playgroup WHERE name = :NAME ");
1424 playGroup->setName(query.
value(0).toString());
1425 playGroup->setTitleMatch(query.
value(1).toString());
1426 playGroup->setSkipAhead(query.
value(2).toInt());
1427 playGroup->setSkipBack(query.
value(3).toInt());
1428 playGroup->setTimeStretch(query.
value(4).toInt());
1429 playGroup->setJump(query.
value(5).toInt());
1433 throw QString(
"Play Group Not Found.");
1442 if (
Name.compare(
"Default", Qt::CaseInsensitive) == 0)
1443 throw QString(
"ERROR: Cannot delete Default entry");
1445 query.
prepare(
"DELETE FROM playgroup "
1446 "WHERE name = :NAME");
1450 return query.
exec();
1462 query.
prepare(
"INSERT INTO playgroup "
1463 "(name, titlematch, skipahead, skipback, timestretch, jump) "
1464 " VALUES(:NAME, :TITLEMATCH, :SKIPAHEAD, :SKIPBACK, :TIMESTRETCH, :JUMP)");
1472 return query.
exec();
1483 throw QString(
"ERROR: Name is not specified");
1487 QString sql =
"UPDATE playgroup SET ";
1490 sql.append(
" titlematch = :TITLEMATCH ");
1497 sql.append(
" skipahead = :SKIPAHEAD ");
1504 sql.append(
" skipback = :SKIPBACK ");
1511 sql.append(
" timestretch = :TIMESTRETCH ");
1518 sql.append(
" jump = :JUMP ");
1523 sql.append(
" WHERE name = :NAME ");
1553 query.
prepare(
"SELECT filterid, description, newruledefault "
1554 "FROM recordfilter ORDER BY filterid");
1558 while (query.
next())
1561 ruleFilter->setId(query.
value(0).toInt());
1562 ruleFilter->setDescription(QObject::tr(query.
value(1).toString()
1563 .toUtf8().constData()));
1578 QString querystr =
"SELECT DISTINCT title FROM recorded "
1579 "WHERE deletepending = 0";
1581 if (!RecGroup.isEmpty())
1582 querystr +=
" AND recgroup = :RECGROUP";
1584 querystr +=
" AND recgroup != 'Deleted'";
1586 querystr +=
" ORDER BY title";
1590 if (!RecGroup.isEmpty())
1600 while (query.
next())
1601 result << query.
value(0).toString();
1614 QString querystr = QString(
1615 "SELECT title, inetref, count(title) as count "
1616 " FROM recorded AS r "
1617 " JOIN recgroups AS g ON r.recgroupid = g.recgroupid "
1618 " WHERE g.recgroup NOT IN ('Deleted', 'LiveTV') "
1619 " AND r.deletepending = 0 "
1620 " GROUP BY title, inetref "
1632 while (query.
next())
1634 V2TitleInfo *pTitleInfo = pTitleInfos->AddNewTitleInfo();
1636 pTitleInfo->setTitle(query.
value(0).toString());
1637 pTitleInfo->setInetref(query.
value(1).toString());
1638 pTitleInfo->setCount(query.
value(2).toInt());
1648 const QString &Sort )
1659 pPrograms->setStartIndex ( nStartIndex );
1660 pPrograms->setCount ( nCount );
1661 pPrograms->setTotalAvailable( size );
1663 pPrograms->setVersion ( MYTH_BINARY_VERSION );
1664 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1674 const QString &Sort,
1675 const QString &RecGroup )
1681 QMetaEnum meta = QMetaEnum::fromType<RecStatus::Type>();
1683 nRecStatus = meta.keyToValue(
RecStatus.toLocal8Bit().constData(), &ok);
1701 pPrograms->setStartIndex ( nStartIndex );
1702 pPrograms->setCount ( nCount );
1703 pPrograms->setTotalAvailable( size );
1705 pPrograms->setVersion ( MYTH_BINARY_VERSION );
1706 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1712 const QString& sTitle,
1713 const QString& sSubtitle,
1714 const QString& sDescription,
1715 const QString& sCategory,
1716 const QDateTime& StartTime,
1717 const QDateTime& EndTime,
1718 const QString& sSeriesId,
1719 const QString& sProgramId,
1721 const QString& sStation,
1728 const QString& sInetref,
1730 QString sSearchType,
1732 uint nPreferredInput,
1735 const QDateTime& LastRecorded,
1740 QString sRecProfile,
1742 QString sStorageGroup,
1748 bool bAutoTranscode,
1749 bool bAutoMetaLookup,
1755 const QString& AutoExtend)
1757 QDateTime recstartts = StartTime.toUTC();
1758 QDateTime recendts = EndTime.toUTC();
1759 QDateTime lastrects = LastRecorded.toUTC();
1763 if (sType.isEmpty())
1766 if (sSearchType.isEmpty())
1767 sSearchType =
"none";
1769 if (sDupMethod.isEmpty())
1770 sDupMethod =
"subtitleanddescription";
1772 if (sDupIn.isEmpty())
1792 if (sRecProfile.isEmpty())
1793 sRecProfile =
"Default";
1795 if (sRecGroup.isEmpty())
1796 sRecGroup =
"Default";
1798 if (sStorageGroup.isEmpty())
1799 sStorageGroup =
"Default";
1801 if (sPlayGroup.isEmpty())
1802 sPlayGroup =
"Default";
1860 bool success = rule.
Save();
1862 throw QString(
"DATABASE ERROR: Check for duplicate recording rule");
1870 const QString& sTitle,
1871 const QString& sSubtitle,
1872 const QString& sDescription,
1873 const QString& sCategory,
1874 const QDateTime& StartTime,
1875 const QDateTime& EndTime,
1876 const QString& sSeriesId,
1877 const QString& sProgramId,
1879 const QString& sStation,
1885 const QString& sInetref,
1887 QString sSearchType,
1889 uint nPreferredInput,
1896 QString sRecProfile,
1898 QString sStorageGroup,
1904 bool bAutoTranscode,
1905 bool bAutoMetaLookup,
1911 const QString& AutoExtend)
1913 if (nRecordId == 0 )
1914 throw QString(
"Record ID is invalid.");
1921 throw QString(
"Record ID does not exist.");
1923 QDateTime recstartts = StartTime.toUTC();
1924 QDateTime recendts = EndTime.toUTC();
1927 if (sType.isEmpty())
1930 if (sSearchType.isEmpty())
1931 sSearchType =
"none";
1933 if (sDupMethod.isEmpty())
1934 sDupMethod =
"subtitleanddescription";
1936 if (sDupIn.isEmpty())
1947 if (sRecProfile.isEmpty())
1948 sRecProfile =
"Default";
1950 if (sRecGroup.isEmpty())
1951 sRecGroup =
"Default";
1953 if (sStorageGroup.isEmpty())
1954 sStorageGroup =
"Default";
1956 if (sPlayGroup.isEmpty())
1957 sPlayGroup =
"Default";
1959 if (!sTitle.isEmpty())
1962 if (!sSubtitle.isEmpty())
1965 if(!sDescription.isEmpty())
1968 if (!sCategory.isEmpty())
1971 if (!sSeriesId.isEmpty())
1974 if (!sProgramId.isEmpty())
1979 if (!sStation.isEmpty())
2028 if (!AutoExtend.isEmpty())
2035 bool bResult = pRule.
Save();
2042 bool bResult =
false;
2044 if (nRecordId == 0 )
2045 throw QString(
"Record ID does not exist.");
2050 bResult = pRule.
Delete();
2058 bool bResult =
true;
2060 if (nChanId <= 0 || !dStartTime.isValid())
2061 throw QString(
"Program does not exist.");
2066 throw QString(
"Program does not exist.");
2087 const QString &Sort,
2091 if (Sort.toLower() ==
"lastrecorded")
2093 else if (Sort.toLower() ==
"nextrecording")
2095 else if (Sort.toLower() ==
"title")
2097 else if (Sort.toLower() ==
"priority")
2099 else if (Sort.toLower() ==
"type")
2113 nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (
int)recList.size() ) : 0;
2114 nCount = (nCount > 0) ? std::min( nCount, (
int)recList.size() ) : recList.size();
2115 int nEndIndex = std::min((nStartIndex + nCount), (
int)recList.size() );
2117 for(
int n = nStartIndex; n < nEndIndex; n++)
2121 if (
info !=
nullptr)
2123 V2RecRule *pRecRule = pRecRules->AddNewRecRule();
2131 pRecRules->setStartIndex ( nStartIndex );
2132 pRecRules->setCount ( nCount );
2133 pRecRules->setTotalAvailable( recList.size() );
2135 pRecRules->setVersion ( MYTH_BINARY_VERSION );
2136 pRecRules->setProtoVer ( MYTH_PROTO_VERSION );
2138 while (!recList.empty())
2140 delete recList.back();
2148 const QString& sTemplate,
2151 const QDateTime& StartTime,
2152 bool bMakeOverride )
2155 QDateTime dStartTime = StartTime.toUTC();
2161 throw QString(
"Record ID does not exist.");
2163 else if (!sTemplate.isEmpty())
2166 throw QString(
"Template does not exist.");
2168 else if (nRecordedId > 0)
2173 throw QString(
"Recording does not exist");
2175 else if (nChanId > 0 && dStartTime.isValid())
2182 throw QString(
"Program does not exist.");
2191 throw QString(
"Invalid request.");
2202 bool bResult =
false;
2204 if (nRecordId == 0 )
2205 throw QString(
"Record ID appears invalid.");
2214 bResult = pRule.
Save();
2222 bool bResult =
false;
2224 if (nRecordId == 0 )
2225 throw QString(
"Record ID appears invalid.");
2234 bResult = pRule.
Save();
2253 uint recordedid = 0;
2264 QMetaEnum meta = QMetaEnum::fromType<RecStatus::Type>();
2266 int value = meta.keyToValue(
RecStatus.toLocal8Bit().constData(), &ok);
2278 const QDateTime &StartTime)
2281 QMetaEnum meta = QMetaEnum::fromType<RecStatus::Type>();
2283 int value = meta.keyToValue(
RecStatus.toLocal8Bit().constData(), &ok);
2298 auto enumType =
static_cast<RecordingType>(recType.toInt(&ok, 10));
2308 auto enumType =
static_cast<RecordingType>(recType.toInt(&ok, 10));
2346 const QString &sJobName,
2349 QDateTime JobStartTime,
2350 QString sRemoteHost,
2358 LOG(VB_GENERAL, LOG_ERR,
"JobName and RecordedId are required.");
2362 if (sRemoteHost.isEmpty())
2375 if ( sAction ==
"Remove")
2379 LOG(VB_GENERAL, LOG_ERR,
"For Remove, a valid JobId is required.");
2390 if ( sAction !=
"Add")
2392 LOG(VB_GENERAL, LOG_ERR, QString(
"Illegal Action name '%1'. Use: Add, "
2393 "or Remove").arg(sAction));
2400 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 hasn't been defined.")
2406 sRemoteHost,
false))
2408 LOG(VB_GENERAL, LOG_INFO, QString(
"JobAllow%1 hasn't been setup for "
2409 "host %2 (will be run by default.)")
2410 .arg(sJobName, sRemoteHost));
2413 if (!JobStartTime.isValid())
2414 JobStartTime = QDateTime::currentDateTime();
2419 if (sJobArgs.isNull())
2426 QString(
"Dvr/ManageJobQueue"),
2430 JobStartTime.toUTC());
2434 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 job wasn't queued because of a "
2435 "database error or because it was "
2436 "already running/stopping etc.")
2452 long BookmarkOffset,
2453 const QString &BookmarkOffsetType,
2455 const QString &Description,
2457 const QString &Inetref,
2458 long LastPlayOffset,
2459 const QString &LastPlayOffsetType,
2460 QDate OriginalAirDate,
2464 const QString &SubTitle,
2465 const QString &Title,
2467 const QString &RecGroup )
2472 LOG(VB_GENERAL, LOG_ERR,
"No RecordedId, or no parameters to change.");
2479 if (!ri.GetChanID())
2488 uint64_t position =0;
2490 if (BookmarkOffsetType.toLower() ==
"position")
2492 if (!ri.QueryPositionKeyFrame(&position, BookmarkOffset,
true))
2495 else if (BookmarkOffsetType.toLower() ==
"duration")
2497 if (!ri.QueryDurationKeyFrame(&position, BookmarkOffset,
true))
2502 position = BookmarkOffset;
2505 ri.SaveBookmark(position);
2509 pi.SaveVideoProperties(VID_DAMAGED, Damaged ? VID_DAMAGED : 0);
2516 QString tmp_description;
2517 QString tmp_subtitle;
2521 tmp_description = Description;
2523 tmp_description = ri.GetDescription();
2526 tmp_subtitle = SubTitle;
2528 tmp_subtitle = ri.GetSubtitle();
2533 tmp_title = ri.GetTitle();
2535 ri.ApplyRecordRecTitleChange(tmp_title, tmp_subtitle, tmp_description);
2541 int tmp_episode = 0;
2545 tmp_episode = Episode;
2547 tmp_episode = ri.GetEpisode();
2550 tmp_season = Season;
2552 tmp_season = ri.GetSeason();
2554 pi.SaveSeasonEpisode(tmp_season, tmp_episode);
2558 pi.SaveInetRef(Inetref);
2563 if (LastPlayOffset < 0)
2564 throw QString(
"LastPlayOffset must be >= 0.");
2566 uint64_t position = LastPlayOffset;
2571 if (LastPlayOffsetType.toLower() ==
"position")
2573 if (!ri.QueryPositionKeyFrame(&position, LastPlayOffset, isend))
2576 else if (LastPlayOffsetType.toLower() ==
"duration")
2578 if (!ri.QueryDurationKeyFrame(&position, LastPlayOffset, isend))
2583 ri.SaveLastPlayPos(position);
2592 if (!OriginalAirDate.isValid() && !OriginalAirDate.isNull())
2594 LOG(VB_GENERAL, LOG_ERR,
"Need valid OriginalAirDate yyyy-mm-dd.");
2597 ri.ApplyOriginalAirDateChange(OriginalAirDate);
2601 pi.SavePreserve(Preserve);
2607 LOG(VB_GENERAL, LOG_ERR,
"Recording stars can be 0 to 10.");
2610 ri.ApplyStarsChange(
Stars * 0.1F);
2614 pi.SaveWatched(Watched);
2617 ri.ApplyRecordRecGroupChange(RecGroup);
2629 QString sql(
"SELECT priorityname, recpriority, selectclause "
2630 "FROM powerpriority ");
2632 if (!PriorityName.isEmpty())
2633 sql.append(
" WHERE priorityname = :NAME ");
2637 if (!PriorityName.isEmpty())
2642 while (query.
next())
2645 pRec->setPriorityName(query.
value(0).toString());
2646 pRec->setRecPriority(query.
value(1).toInt());
2647 pRec->setSelectClause(query.
value(2).toString());
2652 throw (QString(
"Error accessing powerpriority table"));
2660 if (PriorityName.isEmpty())
2664 query.
prepare(
"DELETE FROM powerpriority WHERE priorityname = :PRIORITYNAME");
2665 query.
bindValue(
":PRIORITYNAME", PriorityName);
2667 return query.
exec();
2672 const QString & SelectClause )
2674 if (PriorityName.isEmpty())
2675 throw QString(
"ERROR: PriorityName is not specified");
2676 if (SelectClause.isEmpty())
2677 throw QString(
"ERROR: SelectClause is required");
2679 if (! msg.isEmpty() )
2680 throw std::move(msg);
2682 query.
prepare(
"INSERT INTO powerpriority "
2683 " (priorityname, recpriority, selectclause) "
2684 " VALUES(:PRIORITYNAME, :RECPRIORITY, :SELECTCLAUSE) ");
2685 query.
bindValue(
":PRIORITYNAME", PriorityName);
2686 query.
bindValue(
":RECPRIORITY", RecPriority);
2687 query.
bindValue(
":SELECTCLAUSE", SelectClause);
2689 throw(query.
lastError().databaseText());
2695 const QString & SelectClause )
2697 if (PriorityName.isEmpty())
2698 throw QString(
"ERROR: PriorityName is not specified");
2700 throw QString(
"ERROR: RecPriority or SelectClause is required");
2705 if (! msg.isEmpty() )
2706 throw std::move(msg);
2710 QString sql(
"UPDATE powerpriority SET ");
2713 sql.append(
" recpriority = :RECPRIORITY ");
2720 sql.append(
" selectclause = :SELECTCLAUSE ");
2722 sql.append(
" where priorityname = :PRIORITYNAME ");
2724 query.
bindValue(
":PRIORITYNAME", PriorityName);
2726 query.
bindValue(
":RECPRIORITY", RecPriority);
2728 query.
bindValue(
":SELECTCLAUSE", SelectClause);
2730 throw(query.
lastError().databaseText());
2737 QString sql = QString(
"SELECT (%1) FROM (recordmatch, record, "
2738 "program, channel, capturecard, "
2739 "oldrecorded) WHERE NULL").arg(SelectClause);
2742 int i = sql.indexOf(
"RECTABLE");
2744 sql = sql.replace(i, strlen(
"RECTABLE"),
"record");
2752 msg = tr(
"An error was found when checking") +
":\n\n";
2754 msg +=
"\n\n" + tr(
"The database error was") +
":\n";
2755 msg += query.
lastError().databaseText();
2760#include "moc_v2dvr.cpp"
std::vector< ProgramInfo * > pginfolist_t
static int Reschedule(const MythUtilCommandLineParser &)
Used to expire recordings to make space for new recordings.
void GetAllExpiring(QStringList &strList)
Gets the full list of programs that can expire in expiration order.
static QList< InputInfo > GetAllInputInfo(bool virtTuners)
static QString GetChanNum(int chan_id)
Returns the channel-number string of the given channel.
static bool SafeDeleteJob(int jobID, int jobType, int chanid, const QDateTime &recstartts)
static bool InJobRunWindow(QDateTime jobstarttsRaw)
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())
static int GetJobID(int jobType, uint chanid, const QDateTime &recstartts)
static int GetJobTypeFromName(const QString &name)
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QString executedQuery(void) const
QSqlError lastError(void) const
QVariant value(int i) const
int numRowsAffected() const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
QString GetHostName(void)
MythScheduler * GetScheduler(void)
QString GetSetting(const QString &key, const QString &defaultval="")
void dispatch(const MythEvent &event)
bool GetBoolSettingOnHost(const QString &key, const QString &host, bool defaultval=false)
static void DBError(const QString &where, const MSqlQuery &query)
This class is used as a container for messages.
bool HAS_PARAMv2(const QString &p)
virtual QMap< QString, ProgramInfo * > GetRecording(void) const =0
static QStringList GetNames(void)
Holds information on recordings and videos.
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
static uint SubtitleTypesFromNames(const QString &names)
void QueryMarkup(QVector< MarkupEntry > &mapMark, QVector< MarkupEntry > &mapSeek) const
bool HasPathname(void) const
void SavePreserve(bool preserveEpisode)
Set "preserve" field in "recorded" table to "preserveEpisode".
bool IsCommercialFlagged(void) const
bool IsAutoExpirable(void) const
bool IsPreserved(void) const
void SaveWatched(bool watchedFlag)
Set "watched" field in recorded/videometadata to "watchedFlag".
void SaveAutoExpire(AutoExpireType autoExpire, bool updateDelete=false)
Set "autoexpire" field in "recorded" table to "autoExpire".
uint GetRecordingID(void) const
void ProgramFlagsFromNames(const QString &names)
void SetRecordingStatus(RecStatus::Type status)
void SaveMarkup(const QVector< MarkupEntry > &mapMark, const QVector< MarkupEntry > &mapSeek) const
bool QueryKeyFrameDuration(uint64_t *duration, uint64_t keyframe, bool backwards) const
static uint AudioPropertiesFromNames(const QString &names)
static QMap< QString, bool > QueryJobsRunning(int type)
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
bool QueryPositionKeyFrame(uint64_t *keyframe, uint64_t position, bool backwards) const
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
void SaveLastPlayPos(uint64_t frame)
TODO Move to RecordingInfo.
bool QueryKeyFramePosition(uint64_t *position, uint64_t keyframe, bool backwards) const
static uint VideoPropertiesFromNames(const QString &names)
bool QueryDurationKeyFrame(uint64_t *keyframe, uint64_t duration, bool backwards) const
bool IsWatched(void) const
static bool QueryRecordedIdFromPathname(const QString &pathname, uint &recordedid)
static QMap< QString, uint32_t > QueryInUseMap(void)
uint64_t QueryLastPlayPos(void) const
Gets any lastplaypos position in database, unless the ignore lastplaypos flag is set.
uint64_t QueryBookmark(void) const
Gets any bookmark position in database, unless the ignore bookmark flag is set.
void SaveCommFlagged(CommFlagStatus flag)
Set "commflagged" field in "recorded" table to "flag".
void SendUpdateEvent(void) const
Sends event out that the ProgramInfo should be reloaded.
void SaveBookmark(uint64_t frame)
Clears any existing bookmark in DB and if frame is greater than 0 sets a new bookmark.
static QString toDescription(Type recstatus, RecordingType rectype, const QDateTime &recstartts)
Converts "recstatus" into a long human readable description.
static QString toString(RecStatus::Type recstatus, uint id)
Converts "recstatus" into a short (unreadable) string.
Holds information on a TV Program one might wish to record.
void ApplyRecordStateChange(RecordingType newstate, bool save=true)
Sets RecordingType of "record", creating "record" if it does not exist.
void ApplyNeverRecord(void)
Set this program to never be recorded by inserting 'history' for it into the database with a status o...
void ForgetHistory(void)
Forget the recording of a program so it will be recorded again.
bool InsertRecording(const QString &ext, bool force_match=false)
static bool QueryRecordedIdForKey(int &recordedid, uint chanid, const QDateTime &recstartts)
void ReactivateRecording(void)
Asks the scheduler to restart this recording if possible.
static uint GetRecgroupID(const QString &recGroup)
Temporary helper during transition from string to ID.
Internal representation of a recording rule, mirrors the record table.
int m_findday
Day of the week for once per week etc.
bool LoadTemplate(const QString &title, const QString &category="Default", const QString &categoryType="Default")
RecSearchType m_searchType
bool LoadByProgram(const ProgramInfo *proginfo)
bool IsValid(QString &msg) const
QTime m_findtime
Time for timeslot rules.
int m_recordID
Unique Recording Rule ID.
RecordingDupInType m_dupIn
bool m_isInactive
Recording rule is enabled?
bool Save(bool sendSig=true)
RecordingDupMethodType m_dupMethod
bool Load(bool asTemplate=false)
Load a single rule from the recorded table.
bool Delete(bool sendSig=true)
bool m_autoMetadataLookup
AutoExtendType m_autoExtend
static void RescheduleMatch(uint recordid, uint sourceid, uint mplexid, const QDateTime &maxstarttime, const QString &why)
static void GetAllScheduled(QStringList &strList, SchedSortColumn sortBy=kSortTitle, bool ascending=true)
Returns all scheduled programs serialized into a QStringList.
static QStringList getRecordingsGroups(void)
static bool AddPlayGroup(const QString &Name, const QString &TitleMatch, int SkipAhead, int SkipBack, int TimeStretch, int Jump)
static long GetSavedBookmark(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType)
static void RegisterCustomTypes()
static V2EncoderList * GetEncoderList()
static bool RescheduleRecordings(void)
static uint AddRecordSchedule(const QString &Title, const QString &Subtitle, const QString &Description, const QString &Category, const QDateTime &StartTime, const QDateTime &EndTime, 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 &LastRecorded, 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, const QString &AutoExtend)
static QStringList GetTitleList(const QString &RecGroup)
static QString DupInToDescription(const QString &DupIn)
static bool RemovePowerPriority(const QString &PriorityName)
static bool RemoveRecordSchedule(uint RecordId)
static bool StopRecording(int RecordedId)
static int RecordedIdForKey(int ChanId, const QDateTime &StartTime)
static V2ProgramList * GetUpcomingList(int StartIndex, int Count, bool ShowAll, int RecordId, const QString &RecStatus, const QString &Sort, const QString &RecGroup)
static int RecordedIdForPathname(const QString &Pathname)
static V2MarkupList * GetRecordedMarkup(int RecordedId)
static V2PowerPriorityList * GetPowerPriorityList(const QString &PriorityName)
static int AddRecordedProgram(const QString &Program)
static V2RecRuleList * GetRecordScheduleList(int StartIndex, int Count, const QString &Sort, bool Descending)
static QString RecStatusToDescription(const QString &RecStatus, int RecType, const QDateTime &StartTime)
static V2CutList * GetRecordedSeek(int RecordedId, const QString &OffsetType)
static QStringList GetProgramCategories(bool OnlyRecorded)
static QString CheckPowerQuery(const QString &SelectClause)
static bool UnDeleteRecording(int RecordedId, int ChanId, const QDateTime &StartTime)
static V2PlayGroup * GetPlayGroup(const QString &Name)
static bool AllowReRecord(int RecordedId, int ChanId, const QDateTime &StartTime)
bool UpdatePlayGroup(const QString &Name, const QString &TitleMatch, int SkipAhead, int SkipBack, int TimeStretch, int Jump)
bool UpdateRecordedMetadata(uint RecordedId, bool AutoExpire, long BookmarkOffset, const QString &BookmarkOffsetType, bool Damaged, const QString &Description, uint Episode, const QString &Inetref, long LastPlayOffset, const QString &LastPlayOffsetType, QDate OriginalAirDate, bool Preserve, uint Season, uint Stars, const QString &SubTitle, const QString &Title, bool Watched, const QString &RecGroup)
static bool EnableRecordSchedule(uint RecordId)
static QString DupMethodToDescription(const QString &DupMethod)
static bool DeleteRecording(int RecordedId, int ChanId, const QDateTime &StartTime, bool ForceDelete, bool AllowRerecord)
static V2ProgramList * GetConflictList(int StartIndex, int Count, int RecordId, const QString &Sort)
static bool SetRecordedMarkup(int RecordedId, const QString &MarkupList)
static bool SetSavedBookmark(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType, long Offset)
static V2InputList * GetInputList()
static QStringList GetRecGroupList(const QString &UsedBy)
static bool RemovePlayGroup(const QString &Name)
static V2CutList * GetRecordedCommBreak(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType, bool IncludeFps)
static QString DupMethodToString(const QString &DupMethod)
static V2TitleInfoList * GetTitleInfoList()
static long GetLastPlayPos(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType)
static bool DisableRecordSchedule(uint RecordId)
static V2RecRule * GetRecordSchedule(uint RecordId, const QString &Template, int RecordedId, int ChanId, const QDateTime &StartTime, bool MakeOverride)
static bool AddRecordedCredits(int RecordedId, const QString &Cast)
static QString DupInToString(const QString &DupIn)
static QString RecStatusToString(const QString &RecStatus)
static V2CutList * GetRecordedCutList(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType, bool IncludeFps)
static QStringList GetRecStorageGroupList()
V2ProgramList * 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, bool IncChannel, bool Details, bool IncCast, bool IncArtWork, bool IncRecording)
static QStringList GetPlayGroupList()
static bool ReactivateRecording(int RecordedId, int ChanId, const QDateTime &StartTime, int RecordId)
static QString RecTypeToString(const QString &RecType)
static V2ProgramList * GetOldRecordedList(bool Descending, int StartIndex, int Count, const QDateTime &StartTime, const QDateTime &EndTime, const QString &Title, const QString &TitleRegEx, const QString &SubtitleRegEx, const QString &SeriesId, int RecordId, const QString &Sort)
static V2Program * GetRecorded(int RecordedId, int ChanId, const QDateTime &StartTime)
static bool RemoveRecorded(int RecordedId, int ChanId, const QDateTime &StartTime, bool ForceDelete, bool AllowRerecord)
bool RemoveOldRecorded(int ChanId, const QDateTime &StartTime, bool Reschedule)
static bool UpdateRecordedWatchedStatus(int RecordedId, int ChanId, const QDateTime &StartTime, bool Watched)
static bool SetLastPlayPos(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType, long Offset)
int ManageJobQueue(const QString &Action, const QString &JobName, int JobId, int RecordedId, QDateTime JobStartTime, QString RemoteHost, QString JobArgs)
static QString RecTypeToDescription(const QString &RecType)
bool UpdatePowerPriority(const QString &PriorityName, int RecPriority, const QString &SelectClause)
static bool AddDontRecordSchedule(int ChanId, const QDateTime &StartTime, bool NeverRecord)
static V2RecRuleFilterList * GetRecRuleFilterList()
static V2ProgramList * GetExpiringList(int StartIndex, int Count)
bool UpdateOldRecorded(int ChanId, const QDateTime &StartTime, bool Duplicate, bool Reschedule)
static bool UpdateRecordSchedule(uint RecordId, const QString &Title, const QString &Subtitle, const QString &Description, const QString &Category, const QDateTime &StartTime, const QDateTime &EndTime, 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, const QString &AutoExtend)
static bool AddPowerPriority(const QString &PriorityName, int RecPriority, const QString &SelectClause)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
std::deque< RecordingInfo * > RecList
std::shared_ptr< MythSortHelper > getMythSortHelper(void)
Get a pointer to the MythSortHelper singleton.
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
std::vector< DBPerson > DBCredits
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)
ProgramInfo::CategoryType string_to_myth_category_type(const QString &category_type)
ProgramInfo * LoadProgramFromProgram(const uint chanid, const QDateTime &starttime)
bool LoadFromOldRecorded(ProgramList &destination, const QString &sql, const MSqlBindings &bindings)
MarkTypes markTypeFromString(const QString &str)
RecordingDupMethodType dupMethodFromString(const QString &type)
RecordingDupInType dupInFromString(const QString &type)
RecordingType recTypeFromString(const QString &type)
QString toDescription(RecordingType rectype)
Converts "rectype" into a human readable description.
RecSearchType searchTypeFromString(const QString &type)
AutoExtendType autoExtendTypeFromString(const QString &type)
RecordingDupInType dupInFromStringAndBool(const QString &type, bool newEpisodesOnly)
Q_GLOBAL_STATIC_WITH_ARGS(MythHTTPMetaService, s_service,(DVR_HANDLE, V2Dvr::staticMetaObject, &V2Dvr::RegisterCustomTypes)) void V2Dvr
void FillEncoderList(QVariantList &list, QObject *parent)
void V2FillInputInfo(V2Input *input, const InputInfo &inputInfo)
void V2FillCommBreak(V2CutList *pCutList, ProgramInfo *rInfo, int marktype, bool includeFps)
DBCredits * V2jsonCastToCredits(const QJsonObject &cast)
void V2FillRecRuleInfo(V2RecRule *pRecRule, RecordingRule *pRule)
void V2FillProgramInfo(V2Program *pProgram, ProgramInfo *pInfo, bool bIncChannel, bool bDetails, bool bIncCast, bool bIncArtwork, bool bIncRecording)
int FillUpcomingList(QVariantList &list, QObject *parent, int &nStartIndex, int &nCount, bool bShowAll, int nRecordId, int nRecStatus, const QString &Sort, const QString &RecGroup)
void V2FillSeek(V2CutList *pCutList, RecordingInfo *rInfo, MarkTypes marktype)
int V2CreateRecordingGroup(const QString &groupName)
void V2FillCutList(V2CutList *pCutList, ProgramInfo *rInfo, int marktype, bool includeFps)