28#include <QJsonDocument>
36#include "libmythbase/mythversion.h"
61 qRegisterMetaType<V2ProgramList*>(
"V2ProgramList");
62 qRegisterMetaType<V2Program*>(
"V2Program");
63 qRegisterMetaType<V2CutList*>(
"V2CutList");
64 qRegisterMetaType<V2Cutting*>(
"V2Cutting");
65 qRegisterMetaType<V2MarkupList*>(
"V2MarkupList");
66 qRegisterMetaType<V2Markup*>(
"V2Markup");
67 qRegisterMetaType<V2EncoderList*>(
"V2EncoderList");
68 qRegisterMetaType<V2Encoder*>(
"V2Encoder");
69 qRegisterMetaType<V2InputList*>(
"V2InputList");
70 qRegisterMetaType<V2Input*>(
"V2Input");
71 qRegisterMetaType<V2RecRuleFilterList*>(
"V2RecRuleFilterList");
72 qRegisterMetaType<V2RecRuleFilter*>(
"V2RecRuleFilter");
73 qRegisterMetaType<V2TitleInfoList*>(
"V2TitleInfoList");
74 qRegisterMetaType<V2TitleInfo*>(
"V2TitleInfo");
75 qRegisterMetaType<V2RecRule*>(
"V2RecRule");
76 qRegisterMetaType<V2RecRuleList*>(
"V2RecRuleList");
77 qRegisterMetaType<V2ChannelInfo*>(
"V2ChannelInfo");
78 qRegisterMetaType<V2RecordingInfo*>(
"V2RecordingInfo");
79 qRegisterMetaType<V2ArtworkInfoList*>(
"V2ArtworkInfoList");
80 qRegisterMetaType<V2ArtworkInfo*>(
"V2ArtworkInfo");
81 qRegisterMetaType<V2CastMemberList*>(
"V2CastMemberList");
82 qRegisterMetaType<V2CastMember*>(
"V2CastMember");
83 qRegisterMetaType<V2PlayGroup*>(
"V2PlayGroup");
84 qRegisterMetaType<V2PowerPriority*>(
"V2PowerPriority");
85 qRegisterMetaType<V2PowerPriorityList*>(
"V2PowerPriorityList");
107 nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (
int)infoList.size() ) : 0;
108 nCount = (nCount > 0) ? std::min( nCount, (
int)infoList.size() ) : infoList.size();
109 int nEndIndex = std::min((nStartIndex + nCount), (
int)infoList.size() );
111 for(
int n = nStartIndex; n < nEndIndex; n++)
115 if (pInfo !=
nullptr)
117 V2Program *pProgram = pPrograms->AddNewProgram();
127 pPrograms->setStartIndex ( nStartIndex );
128 pPrograms->setCount ( nCount );
129 pPrograms->setTotalAvailable( infoList.size() );
131 pPrograms->setVersion ( MYTH_BINARY_VERSION );
132 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
140 const QString &sTitleRegEx,
141 const QString &sRecGroup,
142 const QString &sStorageGroup,
143 const QString &sCategory,
144 const QString &sSort,
167 bIncRecording =
true;
169 QMap< QString, ProgramInfo* > recMap;
183 if (bIgnoreLiveTV && (sRecGroup ==
"LiveTV"))
185 bIgnoreLiveTV =
false;
186 LOG(VB_GENERAL, LOG_ERR, QString(
"Setting Ignore%1=false because RecGroup=%1")
190 if (bIgnoreDeleted && (sRecGroup ==
"Deleted"))
192 bIgnoreDeleted =
false;
193 LOG(VB_GENERAL, LOG_ERR, QString(
"Setting Ignore%1=false because RecGroup=%1")
198 sSort, bIgnoreLiveTV, bIgnoreDeleted );
200 QMap< QString, ProgramInfo* >::iterator mit = recMap.begin();
202 for (; mit != recMap.end(); mit = recMap.erase(mit))
213 int nMax = (nCount > 0) ? nCount : progList.
size();
218 QRegularExpression rTitleRegEx
219 { sTitleRegEx, QRegularExpression::CaseInsensitiveOption };
221 for (
auto *pInfo : progList)
223 if (pInfo->IsDeletePending() ||
224 (!sTitleRegEx.isEmpty() && !pInfo->GetTitle().contains(rTitleRegEx)) ||
225 (!sRecGroup.isEmpty() && sRecGroup != pInfo->GetRecordingGroup()) ||
226 (!sStorageGroup.isEmpty() && sStorageGroup != pInfo->GetStorageGroup()) ||
227 (!sCategory.isEmpty() && sCategory != pInfo->GetCategory()))
230 if ((nAvailable < nStartIndex) ||
240 V2Program *pProgram = pPrograms->AddNewProgram();
241 V2FillProgramInfo( pProgram, pInfo, bIncChannel, bDetails, bIncCast, bIncArtWork, bIncRecording );
246 pPrograms->setStartIndex ( nStartIndex );
247 pPrograms->setCount ( nCount );
248 pPrograms->setTotalAvailable( nAvailable );
250 pPrograms->setVersion ( MYTH_BINARY_VERSION );
251 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
264 const QDateTime &sStartTime,
265 const QDateTime &sEndTime,
266 const QString &sTitle,
267 const QString &TitleRegEx,
268 const QString &SubtitleRegEx,
269 const QString &sSeriesId,
271 const QString &sSort)
273 if (!sStartTime.isNull() && !sStartTime.isValid())
274 throw QString(
"StartTime is invalid");
276 if (!sEndTime.isNull() && !sEndTime.isValid())
277 throw QString(
"EndTime is invalid");
279 const QDateTime& dtStartTime = sStartTime;
280 const QDateTime& dtEndTime = sEndTime;
282 if (!sEndTime.isNull() && dtEndTime < dtStartTime)
283 throw QString(
"EndTime is before StartTime");
293 if (!dtStartTime.isNull())
295 sSQL +=
" AND endtime >= :StartDate ";
296 bindings[
":StartDate"] = dtStartTime;
299 if (!dtEndTime.isNull())
301 sSQL +=
" AND starttime <= :EndDate ";
302 bindings[
":EndDate"] = dtEndTime;
309 clause <<
"recordid = :RecordId";
310 bindings[
":RecordId"] = nRecordId;
313 if (!sTitle.isEmpty())
315 clause <<
"title = :Title";
316 bindings[
":Title"] = sTitle;
319 if (!TitleRegEx.isEmpty())
321 clause <<
"title REGEXP :TitleRegEx";
322 bindings[
":TitleRegEx"] = TitleRegEx;
325 if (!SubtitleRegEx.isEmpty())
327 clause <<
"subtitle REGEXP :SubtitleRegEx";
328 bindings[
":SubtitleRegEx"] = SubtitleRegEx;
331 if (!sSeriesId.isEmpty())
333 clause <<
"seriesid = :SeriesId";
334 bindings[
":SeriesId"] = sSeriesId;
337 if (!clause.isEmpty())
339 sSQL += QString(
" AND (%1) ").arg(clause.join(
" AND "));
342 QStringList sortByFields;
343 sortByFields <<
"starttime" <<
"title" <<
"subtitle" <<
"season" <<
"episode" <<
"category"
344 <<
"channum" <<
"rectype" <<
"recstatus" <<
"duration" ;
345 QStringList fields = sSort.split(
",");
347 fields <<
"starttime";
348 sSQL +=
" ORDER BY ";
350 for (
const QString& oneField : std::as_const(fields))
352 QString field = oneField.simplified().toLower();
355 if (sortByFields.contains(field))
361 if (field ==
"channum")
364 field =
"channum*1000-ifnull(regexp_substr(channum,'-.*'),0)";
366 else if (field ==
"duration")
368 field =
"timestampdiff(second,starttime,endtime)";
370 else if (field ==
"title")
373 QString prefixes = sh->getPrefixes();
374 field =
"REGEXP_REPLACE(title,'" + prefixes +
"','')";
376 else if (field ==
"subtitle")
379 QString prefixes = sh->getPrefixes();
380 field =
"REGEXP_REPLACE(subtitle,'" + prefixes +
"','')";
390 LOG(VB_GENERAL, LOG_WARNING, QString(
"V2Dvr::GetOldRecordedList() got an unknown sort field '%1' - ignoring").arg(oneField));
394 uint nTotalAvailable = (nStartIndex == 0) ? 1 : 0;
396 (
uint)nStartIndex, (
uint)nCount, nTotalAvailable );
404 nCount = (int)progList.
size();
405 int nEndIndex = (int)progList.
size();
407 for(
int n = 0; n < nEndIndex; n++)
411 V2Program *pProgram = pPrograms->AddNewProgram();
418 pPrograms->setStartIndex ( nStartIndex );
419 pPrograms->setCount ( nCount );
420 pPrograms->setTotalAvailable( nTotalAvailable );
422 pPrograms->setVersion ( MYTH_BINARY_VERSION );
423 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
429 const QDateTime &StartTime,
433 throw QString(
"Channel ID and StartTime appears invalid.");
434 QString sql(
"DELETE FROM oldrecorded "
435 " WHERE chanid = :ChanId AND starttime = :StartTime" );
439 query.
bindValue(
":StartTime", StartTime);
455 const QDateTime &StartTime,
460 throw QString(
"Channel ID and StartTime appears invalid.");
462 throw QString(
"Error: Nothing to change.");
463 QString sql(
"UPDATE oldrecorded "
464 " SET Duplicate = :Duplicate "
465 " WHERE chanid = :ChanId AND starttime = :StartTime" );
468 query.
bindValue(
":Duplicate", Duplicate);
470 query.
bindValue(
":StartTime", StartTime);
488 int chanid,
const QDateTime &StartTime)
490 if ((RecordedId <= 0) &&
491 (chanid <= 0 || !StartTime.isValid()))
492 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
513 QJsonDocument jsonDoc = QJsonDocument::fromJson(Cast.toUtf8());
517 throw QString(
"AddRecordedCredits: recordedid %1 does "
518 "not exist.").arg(RecordedId);
521 if (credits ==
nullptr)
522 throw QString(
"AddRecordedCredits: Failed to parse cast from json.");
525 for (
auto & person : *credits)
527 if (!person.InsertDB(query, ri.
GetChanID(),
529 throw QString(
"AddRecordedCredits: Failed to add credit "
530 "%1 to DB").arg(person.toString());
542 QJsonDocument doc = QJsonDocument::fromJson(Program.toUtf8());
543 QJsonObject program = doc.object();
544 QJsonObject channel = program[
"Channel"].toObject();
545 QJsonObject recording = program[
"Recording"].toObject();
546 QJsonObject cast = program[
"Cast"].toObject();
549 int chanid = channel.value(
"ChanId").toVariant().toString().toUInt();
551 QString
hostname = program[
"HostName"].toString(
"");
554 throw QString(
"AddRecordedProgram: chanid %1 does "
555 "not exist.").arg(chanid);
557 pi->m_title = program.value(
"Title").toString(
"");
558 pi->m_subtitle = program.value(
"SubTitle").toString(
"");
559 pi->m_description = program.value(
"Description").toString(
"");
560 pi->m_category = program.value(
"Category").toString(
"");
567 pi->m_airdate = pi->m_originalairdate.year();
568 pi->m_partnumber = program.value(
"PartNumber").toString(
"0").toUInt();
569 pi->m_parttotal = program.value(
"PartTotal").toString(
"0").toUInt();
570 pi->m_syndicatedepisodenumber =
"";
572 (program.value(
"SubPropNames").toString(
""));
574 (program.value(
"AudioPropNames").toString(
""));
576 (program.value(
"VideoPropNames").toString(
""));
577 pi->m_stars = program.value(
"Stars").toVariant().toString().toFloat();
579 pi->m_seriesId = program.value(
"SeriesId").toString(
"");
580 pi->m_programId = program.value(
"ProgramId").toString(
"");
581 pi->m_inetref = program.value(
"Inetref").toString(
"");
582 pi->m_previouslyshown =
false;
583 pi->m_listingsource = 0;
586 pi->m_season = program.value(
"Season").toVariant()
587 .toString().toUInt();
588 pi->m_episode = program.value(
"Episode").toVariant()
589 .toString().toUInt();
590 pi->m_totalepisodes = program.value(
"TotalEpisodes").toVariant()
591 .toString().toUInt();
593 pi->m_channel = channel.value(
"ChannelName").toString(
"");
595 pi->m_startts = recording.value(
"StartTs").toString(
"");
596 pi->m_endts = recording.value(
"EndTs").toString(
"");
600 pi->m_title_pronounce =
"";
603 pi->m_colorcode =
"";
611 if (!pi->InsertDB(query, chanid,
true))
613 throw QString(
"AddRecordedProgram: "
614 "Failed to add recordedprogram entry.");
619 pi->m_subtitle, pi->m_subtitle,
621 pi->m_season, pi->m_episode,
623 pi->m_syndicatedepisodenumber,
626 channel.value(
"ChanNum").toString(
"0"),
627 channel.value(
"CallSign").toString(
""),
629 recording.value(
"RecGroup").toString(
""),
630 recording.value(
"PlayGroup").toString(
""),
632 recording.value(
"StorageGroup").toString(
""),
640 recording.value(
"Priority").toString(
"0").toInt(),
646 pi->m_originalairdate,
647 program.value(
"Repeat").toString(
"false").toLower() ==
"true",
650 recording.value(
"RecordedId").toString(
"0").toInt(),
652 static_cast<RecordingType>(recording.value(
"RecType").toInt()),
655 channel.value(
"SourceId").toVariant().toString().toUInt(),
656 channel.value(
"InputId").toVariant().toString().toUInt(),
658 channel.value(
"CommFree").toBool(),
666 recording.value(
"EncoderName").toString(
""));
670 QString
filename = program.value(
"FileName").toString(
"");
672 int idx =
filename.lastIndexOf(
'.');
677 throw QString(
"Failed to create RecordingInfo database entry. "
678 "Non unique starttime?");
701 int chanid,
const QDateTime &StartTime,
702 bool forceDelete,
bool allowRerecord)
710 int chanid,
const QDateTime &StartTime,
711 bool forceDelete,
bool allowRerecord)
713 if ((RecordedId <= 0) &&
714 (chanid <= 0 || !StartTime.isValid()))
715 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
726 QString cmd = QString(
"DELETE_RECORDING %1 %2 %3 %4")
729 forceDelete ?
"FORCE" :
"NO_FORCE",
730 allowRerecord ?
"FORGET" :
"NO_FORGET");
745 int chanid,
const QDateTime &StartTime)
747 if ((RecordedId <= 0) &&
748 (chanid <= 0 || !StartTime.isValid()))
749 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
759 QString cmd = QString(
"UNDELETE_RECORDING %1 %2")
778 throw QString(
"RecordedId param is invalid.");
784 QString cmd = QString(
"STOP_RECORDING %1 %2")
792 throw QString(
"RecordedId %1 not found").arg(RecordedId);
807 int ChanId,
const QDateTime &StartTime,
815 else if (ChanId > 0 && StartTime.isValid())
819 else if (RecordId > 0)
823 query.
prepare(
"SELECT recordedid FROM recorded "
824 " WHERE recordid = :RECORDID "
825 " ORDER BY starttime DESC LIMIT 1");
834 recId = query.
value(0).toInt();
841 throw QString(
"Recorded ID or Channel ID and StartTime or RecordId are invalid.");
859 "RescheduleRecordings");
871 if (ChanId > 0 || StartTime.isValid())
872 throw QString(
"ERROR RecordedId param cannot be used with ChanId or StartTime.");
876 if (!StartTime.isValid())
877 throw QString(
"ERROR ChanId param requires a valid StartTime.");
881 throw QString(
"ERROR RecordedId or (ChanId and StartTime) required.");
888 throw QString(
"ERROR RecordedId %1 not found").arg(RecordedId);
894 if (progInfo ==
nullptr)
895 throw QString(
"ERROR Guide data for Chanid %1 at StartTime %2 not found")
896 .arg(ChanId).arg(StartTime.toString());
910 const QDateTime &StartTime,
915 if ((RecordedId <= 0) &&
916 (chanid <= 0 || !StartTime.isValid()))
917 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
941 const QDateTime &StartTime,
942 const QString &offsettype )
944 if ((RecordedId <= 0) &&
945 (chanid <= 0 || !StartTime.isValid()))
946 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
959 if (offsettype.toLower() ==
"position"){
965 if (offsettype.toLower() ==
"duration"){
983 const QDateTime &StartTime,
984 const QString &offsettype )
986 if (RecordedId == -1)
989 if ((RecordedId <= 0) &&
990 (chanid <= 0 || !StartTime.isValid()))
991 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1004 if (offsettype.toLower() ==
"position"){
1010 if (offsettype.toLower() ==
"duration"){
1025 const QDateTime &StartTime,
1026 const QString &offsettype,
1031 if ((RecordedId <= 0) &&
1032 (chanid <= 0 || !StartTime.isValid()))
1033 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1036 throw QString(
"Offset must be >= 0.");
1043 uint64_t position = 0;
1045 if (offsettype.toLower() ==
"position"){
1049 else if (offsettype.toLower() ==
"duration"){
1069 const QDateTime &StartTime,
1070 const QString &offsettype,
1075 if ((RecordedId <= 0) &&
1076 (chanid <= 0 || !StartTime.isValid()))
1077 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1080 throw QString(
"Offset must be >= 0.");
1087 uint64_t position = 0;
1089 if (offsettype.toLower() ==
"position"){
1093 else if (offsettype.toLower() ==
"duration"){
1107 const QDateTime &StartTime,
1108 const QString &offsettype,
1112 if ((RecordedId <= 0) &&
1113 (chanid <= 0 || !StartTime.isValid()))
1114 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1123 if (offsettype.toLower() ==
"position")
1125 else if (offsettype.toLower() ==
"duration")
1141 const QDateTime &StartTime,
1142 const QString &offsettype,
1146 if ((RecordedId <= 0) &&
1147 (chanid <= 0 || !StartTime.isValid()))
1148 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1157 if (offsettype.toLower() ==
"position")
1159 else if (offsettype.toLower() ==
"duration")
1174 const QString &offsettype )
1177 if (RecordedId <= 0)
1178 throw QString(
"Recorded ID appears invalid.");
1184 if (offsettype.toLower() ==
"bytes")
1188 else if (offsettype.toLower() ==
"duration")
1195 throw QString(
"Type must be 'BYTES' or 'DURATION'.");
1213 throw QString(
"Invalid RecordedId %1").arg(RecordedId);
1215 QVector<ProgramInfo::MarkupEntry> mapMark;
1216 QVector<ProgramInfo::MarkupEntry> mapSeek;
1221 for (
const auto& entry : std::as_const(mapMark))
1223 V2Markup *pMarkup = pMarkupList->AddNewMarkup();
1225 pMarkup->setType(typestr);
1226 pMarkup->setFrame(entry.frame);
1227 if (entry.isDataNull)
1228 pMarkup->setData(
"NULL");
1230 pMarkup->setData(QString::number(entry.data));
1232 for (
const auto& entry : std::as_const(mapSeek))
1234 V2Markup *pSeek = pMarkupList->AddNewSeek();
1236 pSeek->setType(typestr);
1237 pSeek->setFrame(entry.frame);
1238 if (entry.isDataNull)
1239 pSeek->setData(
"NULL");
1241 pSeek->setData(QString::number(entry.data));
1258 throw QString(
"Invalid RecordedId %1").arg(RecordedId);
1260 QVector<ProgramInfo::MarkupEntry> mapMark;
1261 QVector<ProgramInfo::MarkupEntry> mapSeek;
1263 QJsonDocument doc = QJsonDocument::fromJson(MarkupList.toUtf8());
1264 QJsonObject markuplist = doc.object();
1266 QJsonArray marks = markuplist[
"Mark"].toArray();
1267 for (
const auto & m : std::as_const(marks))
1269 QJsonObject markup = m.toObject();
1272 QString typestr = markup.value(
"Type").toString(
"");
1274 entry.
frame = markup.value(
"Frame").toVariant()
1275 .toString().toLongLong();
1276 QString data = markup.value(
"Data").toString(
"NULL");
1279 entry.
data = data.toLongLong();
1281 mapMark.append(entry);
1284 QJsonArray seeks = markuplist[
"Seek"].toArray();
1285 for (
const auto & m : std::as_const(seeks))
1287 QJsonObject markup = m.toObject();
1290 QString typestr = markup.value(
"Type").toString(
"");
1292 entry.
frame = markup.value(
"Frame").toVariant().toString().toLongLong();
1293 QString data = markup.value(
"Data").toString(
"NULL");
1296 entry.
data = data.toLongLong();
1298 mapSeek.append(entry);
1326 for (
const auto & inputInfo : std::as_const(inputInfoList))
1328 V2Input *input = pList->AddNewInput();
1342 if (UsedBy.compare(
"recorded",Qt::CaseInsensitive) == 0)
1343 query.
prepare(
"SELECT DISTINCT recgroup FROM recorded "
1344 "ORDER BY recgroup");
1345 else if (UsedBy.compare(
"schedule",Qt::CaseInsensitive) == 0)
1346 query.
prepare(
"SELECT DISTINCT recgroup FROM record "
1347 "ORDER BY recgroup");
1349 query.
prepare(
"SELECT recgroup FROM recgroups WHERE recgroup <> 'Deleted' "
1350 "ORDER BY recgroup");
1359 while (query.
next())
1360 result << query.
value(0).toString();
1374 query.
prepare(
"SELECT DISTINCT category FROM recorded ORDER BY category");
1376 query.
prepare(
"SELECT DISTINCT category FROM program ORDER BY category");
1385 while (query.
next())
1386 result << query.
value(0).toString();
1415 query.
prepare(
"SELECT name, titlematch, skipahead, skipback, timestretch, jump "
1416 "FROM playgroup WHERE name = :NAME ");
1423 playGroup->setName(query.
value(0).toString());
1424 playGroup->setTitleMatch(query.
value(1).toString());
1425 playGroup->setSkipAhead(query.
value(2).toInt());
1426 playGroup->setSkipBack(query.
value(3).toInt());
1427 playGroup->setTimeStretch(query.
value(4).toInt());
1428 playGroup->setJump(query.
value(5).toInt());
1432 throw QString(
"Play Group Not Found.");
1441 if (
Name.compare(
"Default", Qt::CaseInsensitive) == 0)
1442 throw QString(
"ERROR: Cannot delete Default entry");
1444 query.
prepare(
"DELETE FROM playgroup "
1445 "WHERE name = :NAME");
1449 return query.
exec();
1461 query.
prepare(
"INSERT INTO playgroup "
1462 "(name, titlematch, skipahead, skipback, timestretch, jump) "
1463 " VALUES(:NAME, :TITLEMATCH, :SKIPAHEAD, :SKIPBACK, :TIMESTRETCH, :JUMP)");
1471 return query.
exec();
1482 throw QString(
"ERROR: Name is not specified");
1486 QString sql =
"UPDATE playgroup SET ";
1489 sql.append(
" titlematch = :TITLEMATCH ");
1496 sql.append(
" skipahead = :SKIPAHEAD ");
1503 sql.append(
" skipback = :SKIPBACK ");
1510 sql.append(
" timestretch = :TIMESTRETCH ");
1517 sql.append(
" jump = :JUMP ");
1522 sql.append(
" WHERE name = :NAME ");
1552 query.
prepare(
"SELECT filterid, description, newruledefault "
1553 "FROM recordfilter ORDER BY filterid");
1557 while (query.
next())
1560 ruleFilter->setId(query.
value(0).toInt());
1561 ruleFilter->setDescription(QObject::tr(query.
value(1).toString()
1562 .toUtf8().constData()));
1577 QString querystr =
"SELECT DISTINCT title FROM recorded "
1578 "WHERE deletepending = 0";
1580 if (!RecGroup.isEmpty())
1581 querystr +=
" AND recgroup = :RECGROUP";
1583 querystr +=
" AND recgroup != 'Deleted'";
1585 querystr +=
" ORDER BY title";
1589 if (!RecGroup.isEmpty())
1599 while (query.
next())
1600 result << query.
value(0).toString();
1613 QString querystr = QString(
1614 "SELECT title, inetref, count(title) as count "
1615 " FROM recorded AS r "
1616 " JOIN recgroups AS g ON r.recgroupid = g.recgroupid "
1617 " WHERE g.recgroup NOT IN ('Deleted', 'LiveTV') "
1618 " AND r.deletepending = 0 "
1619 " GROUP BY title, inetref "
1631 while (query.
next())
1633 V2TitleInfo *pTitleInfo = pTitleInfos->AddNewTitleInfo();
1635 pTitleInfo->setTitle(query.
value(0).toString());
1636 pTitleInfo->setInetref(query.
value(1).toString());
1637 pTitleInfo->setCount(query.
value(2).toInt());
1647 const QString &Sort )
1658 pPrograms->setStartIndex ( nStartIndex );
1659 pPrograms->setCount ( nCount );
1660 pPrograms->setTotalAvailable( size );
1662 pPrograms->setVersion ( MYTH_BINARY_VERSION );
1663 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1673 const QString &Sort,
1674 const QString &RecGroup )
1680 QMetaEnum meta = QMetaEnum::fromType<RecStatus::Type>();
1682 nRecStatus = meta.keyToValue(
RecStatus.toLocal8Bit().constData(), &ok);
1700 pPrograms->setStartIndex ( nStartIndex );
1701 pPrograms->setCount ( nCount );
1702 pPrograms->setTotalAvailable( size );
1704 pPrograms->setVersion ( MYTH_BINARY_VERSION );
1705 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1711 const QString& sTitle,
1712 const QString& sSubtitle,
1713 const QString& sDescription,
1714 const QString& sCategory,
1715 const QDateTime& StartTime,
1716 const QDateTime& EndTime,
1717 const QString& sSeriesId,
1718 const QString& sProgramId,
1720 const QString& sStation,
1727 const QString& sInetref,
1729 QString sSearchType,
1731 uint nPreferredInput,
1734 const QDateTime& LastRecorded,
1739 QString sRecProfile,
1741 QString sStorageGroup,
1747 bool bAutoTranscode,
1748 bool bAutoMetaLookup,
1754 const QString& AutoExtend)
1756 QDateTime recstartts = StartTime.toUTC();
1757 QDateTime recendts = EndTime.toUTC();
1758 QDateTime lastrects = LastRecorded.toUTC();
1762 if (sType.isEmpty())
1765 if (sSearchType.isEmpty())
1766 sSearchType =
"none";
1768 if (sDupMethod.isEmpty())
1769 sDupMethod =
"subtitleanddescription";
1771 if (sDupIn.isEmpty())
1791 if (sRecProfile.isEmpty())
1792 sRecProfile =
"Default";
1794 if (sRecGroup.isEmpty())
1795 sRecGroup =
"Default";
1797 if (sStorageGroup.isEmpty())
1798 sStorageGroup =
"Default";
1800 if (sPlayGroup.isEmpty())
1801 sPlayGroup =
"Default";
1859 bool success = rule.
Save();
1861 throw QString(
"DATABASE ERROR: Check for duplicate recording rule");
1869 const QString& sTitle,
1870 const QString& sSubtitle,
1871 const QString& sDescription,
1872 const QString& sCategory,
1873 const QDateTime& StartTime,
1874 const QDateTime& EndTime,
1875 const QString& sSeriesId,
1876 const QString& sProgramId,
1878 const QString& sStation,
1884 const QString& sInetref,
1886 QString sSearchType,
1888 uint nPreferredInput,
1895 QString sRecProfile,
1897 QString sStorageGroup,
1903 bool bAutoTranscode,
1904 bool bAutoMetaLookup,
1910 const QString& AutoExtend)
1912 if (nRecordId == 0 )
1913 throw QString(
"Record ID is invalid.");
1920 throw QString(
"Record ID does not exist.");
1922 QDateTime recstartts = StartTime.toUTC();
1923 QDateTime recendts = EndTime.toUTC();
1926 if (sType.isEmpty())
1929 if (sSearchType.isEmpty())
1930 sSearchType =
"none";
1932 if (sDupMethod.isEmpty())
1933 sDupMethod =
"subtitleanddescription";
1935 if (sDupIn.isEmpty())
1946 if (sRecProfile.isEmpty())
1947 sRecProfile =
"Default";
1949 if (sRecGroup.isEmpty())
1950 sRecGroup =
"Default";
1952 if (sStorageGroup.isEmpty())
1953 sStorageGroup =
"Default";
1955 if (sPlayGroup.isEmpty())
1956 sPlayGroup =
"Default";
1958 if (!sTitle.isEmpty())
1961 if (!sSubtitle.isEmpty())
1964 if(!sDescription.isEmpty())
1967 if (!sCategory.isEmpty())
1970 if (!sSeriesId.isEmpty())
1973 if (!sProgramId.isEmpty())
1978 if (!sStation.isEmpty())
2027 if (!AutoExtend.isEmpty())
2034 bool bResult = pRule.
Save();
2041 bool bResult =
false;
2043 if (nRecordId == 0 )
2044 throw QString(
"Record ID does not exist.");
2049 bResult = pRule.
Delete();
2057 bool bResult =
true;
2059 if (nChanId <= 0 || !dStartTime.isValid())
2060 throw QString(
"Program does not exist.");
2065 throw QString(
"Program does not exist.");
2086 const QString &Sort,
2090 if (Sort.toLower() ==
"lastrecorded")
2092 else if (Sort.toLower() ==
"nextrecording")
2094 else if (Sort.toLower() ==
"title")
2096 else if (Sort.toLower() ==
"priority")
2098 else if (Sort.toLower() ==
"type")
2112 nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (
int)recList.size() ) : 0;
2113 nCount = (nCount > 0) ? std::min( nCount, (
int)recList.size() ) : recList.size();
2114 int nEndIndex = std::min((nStartIndex + nCount), (
int)recList.size() );
2116 for(
int n = nStartIndex; n < nEndIndex; n++)
2120 if (
info !=
nullptr)
2122 V2RecRule *pRecRule = pRecRules->AddNewRecRule();
2130 pRecRules->setStartIndex ( nStartIndex );
2131 pRecRules->setCount ( nCount );
2132 pRecRules->setTotalAvailable( recList.size() );
2134 pRecRules->setVersion ( MYTH_BINARY_VERSION );
2135 pRecRules->setProtoVer ( MYTH_PROTO_VERSION );
2137 while (!recList.empty())
2139 delete recList.back();
2147 const QString& sTemplate,
2150 const QDateTime& StartTime,
2151 bool bMakeOverride )
2154 QDateTime dStartTime = StartTime.toUTC();
2160 throw QString(
"Record ID does not exist.");
2162 else if (!sTemplate.isEmpty())
2165 throw QString(
"Template does not exist.");
2167 else if (nRecordedId > 0)
2172 throw QString(
"Recording does not exist");
2174 else if (nChanId > 0 && dStartTime.isValid())
2181 throw QString(
"Program does not exist.");
2190 throw QString(
"Invalid request.");
2201 bool bResult =
false;
2203 if (nRecordId == 0 )
2204 throw QString(
"Record ID appears invalid.");
2213 bResult = pRule.
Save();
2221 bool bResult =
false;
2223 if (nRecordId == 0 )
2224 throw QString(
"Record ID appears invalid.");
2233 bResult = pRule.
Save();
2252 uint recordedid = 0;
2263 QMetaEnum meta = QMetaEnum::fromType<RecStatus::Type>();
2265 int value = meta.keyToValue(
RecStatus.toLocal8Bit().constData(), &ok);
2277 const QDateTime &StartTime)
2280 QMetaEnum meta = QMetaEnum::fromType<RecStatus::Type>();
2282 int value = meta.keyToValue(
RecStatus.toLocal8Bit().constData(), &ok);
2297 auto enumType =
static_cast<RecordingType>(recType.toInt(&ok, 10));
2307 auto enumType =
static_cast<RecordingType>(recType.toInt(&ok, 10));
2345 const QString &sJobName,
2348 QDateTime JobStartTime,
2349 QString sRemoteHost,
2357 LOG(VB_GENERAL, LOG_ERR,
"JobName and RecordedId are required.");
2361 if (sRemoteHost.isEmpty())
2374 if ( sAction ==
"Remove")
2378 LOG(VB_GENERAL, LOG_ERR,
"For Remove, a valid JobId is required.");
2389 if ( sAction !=
"Add")
2391 LOG(VB_GENERAL, LOG_ERR, QString(
"Illegal Action name '%1'. Use: Add, "
2392 "or Remove").arg(sAction));
2399 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 hasn't been defined.")
2405 sRemoteHost,
false))
2407 LOG(VB_GENERAL, LOG_INFO, QString(
"JobAllow%1 hasn't been setup for "
2408 "host %2 (will be run by default.)")
2409 .arg(sJobName, sRemoteHost));
2412 if (!JobStartTime.isValid())
2413 JobStartTime = QDateTime::currentDateTime();
2418 if (sJobArgs.isNull())
2425 QString(
"Dvr/ManageJobQueue"),
2429 JobStartTime.toUTC());
2433 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 job wasn't queued because of a "
2434 "database error or because it was "
2435 "already running/stopping etc.")
2451 long BookmarkOffset,
2452 const QString &BookmarkOffsetType,
2454 const QString &Description,
2456 const QString &Inetref,
2457 long LastPlayOffset,
2458 const QString &LastPlayOffsetType,
2459 QDate OriginalAirDate,
2463 const QString &SubTitle,
2464 const QString &Title,
2466 const QString &RecGroup )
2471 LOG(VB_GENERAL, LOG_ERR,
"No RecordedId, or no parameters to change.");
2478 if (!ri.GetChanID())
2487 uint64_t position =0;
2489 if (BookmarkOffsetType.toLower() ==
"position")
2491 if (!ri.QueryPositionKeyFrame(&position, BookmarkOffset,
true))
2494 else if (BookmarkOffsetType.toLower() ==
"duration")
2496 if (!ri.QueryDurationKeyFrame(&position, BookmarkOffset,
true))
2501 position = BookmarkOffset;
2504 ri.SaveBookmark(position);
2508 pi.SaveVideoProperties(VID_DAMAGED, Damaged ? VID_DAMAGED : 0);
2515 QString tmp_description;
2516 QString tmp_subtitle;
2520 tmp_description = Description;
2522 tmp_description = ri.GetDescription();
2525 tmp_subtitle = SubTitle;
2527 tmp_subtitle = ri.GetSubtitle();
2532 tmp_title = ri.GetTitle();
2534 ri.ApplyRecordRecTitleChange(tmp_title, tmp_subtitle, tmp_description);
2540 int tmp_episode = 0;
2544 tmp_episode = Episode;
2546 tmp_episode = ri.GetEpisode();
2549 tmp_season = Season;
2551 tmp_season = ri.GetSeason();
2553 pi.SaveSeasonEpisode(tmp_season, tmp_episode);
2557 pi.SaveInetRef(Inetref);
2562 if (LastPlayOffset < 0)
2563 throw QString(
"LastPlayOffset must be >= 0.");
2565 uint64_t position = LastPlayOffset;
2570 if (LastPlayOffsetType.toLower() ==
"position")
2572 if (!ri.QueryPositionKeyFrame(&position, LastPlayOffset, isend))
2575 else if (LastPlayOffsetType.toLower() ==
"duration")
2577 if (!ri.QueryDurationKeyFrame(&position, LastPlayOffset, isend))
2582 ri.SaveLastPlayPos(position);
2591 if (!OriginalAirDate.isValid() && !OriginalAirDate.isNull())
2593 LOG(VB_GENERAL, LOG_ERR,
"Need valid OriginalAirDate yyyy-mm-dd.");
2596 ri.ApplyOriginalAirDateChange(OriginalAirDate);
2600 pi.SavePreserve(Preserve);
2606 LOG(VB_GENERAL, LOG_ERR,
"Recording stars can be 0 to 10.");
2609 ri.ApplyStarsChange(
Stars * 0.1F);
2613 pi.SaveWatched(Watched);
2616 ri.ApplyRecordRecGroupChange(RecGroup);
2628 QString sql(
"SELECT priorityname, recpriority, selectclause "
2629 "FROM powerpriority ");
2631 if (!PriorityName.isEmpty())
2632 sql.append(
" WHERE priorityname = :NAME ");
2636 if (!PriorityName.isEmpty())
2641 while (query.
next())
2644 pRec->setPriorityName(query.
value(0).toString());
2645 pRec->setRecPriority(query.
value(1).toInt());
2646 pRec->setSelectClause(query.
value(2).toString());
2651 throw (QString(
"Error accessing powerpriority table"));
2659 if (PriorityName.isEmpty())
2663 query.
prepare(
"DELETE FROM powerpriority WHERE priorityname = :PRIORITYNAME");
2664 query.
bindValue(
":PRIORITYNAME", PriorityName);
2666 return query.
exec();
2671 const QString & SelectClause )
2673 if (PriorityName.isEmpty())
2674 throw QString(
"ERROR: PriorityName is not specified");
2675 if (SelectClause.isEmpty())
2676 throw QString(
"ERROR: SelectClause is required");
2678 if (! msg.isEmpty() )
2679 throw std::move(msg);
2681 query.
prepare(
"INSERT INTO powerpriority "
2682 " (priorityname, recpriority, selectclause) "
2683 " VALUES(:PRIORITYNAME, :RECPRIORITY, :SELECTCLAUSE) ");
2684 query.
bindValue(
":PRIORITYNAME", PriorityName);
2685 query.
bindValue(
":RECPRIORITY", RecPriority);
2686 query.
bindValue(
":SELECTCLAUSE", SelectClause);
2688 throw(query.
lastError().databaseText());
2694 const QString & SelectClause )
2696 if (PriorityName.isEmpty())
2697 throw QString(
"ERROR: PriorityName is not specified");
2699 throw QString(
"ERROR: RecPriority or SelectClause is required");
2704 if (! msg.isEmpty() )
2705 throw std::move(msg);
2709 QString sql(
"UPDATE powerpriority SET ");
2712 sql.append(
" recpriority = :RECPRIORITY ");
2719 sql.append(
" selectclause = :SELECTCLAUSE ");
2721 sql.append(
" where priorityname = :PRIORITYNAME ");
2723 query.
bindValue(
":PRIORITYNAME", PriorityName);
2725 query.
bindValue(
":RECPRIORITY", RecPriority);
2727 query.
bindValue(
":SELECTCLAUSE", SelectClause);
2729 throw(query.
lastError().databaseText());
2736 QString sql = QString(
"SELECT (%1) FROM (recordmatch, record, "
2737 "program, channel, capturecard, "
2738 "oldrecorded) WHERE NULL").arg(SelectClause);
2741 int i = sql.indexOf(
"RECTABLE");
2743 sql = sql.replace(i, strlen(
"RECTABLE"),
"record");
2751 msg = tr(
"An error was found when checking") +
":\n\n";
2753 msg +=
"\n\n" + tr(
"The database error was") +
":\n";
2754 msg += query.
lastError().databaseText();
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)