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,
813 else if (ChanId > 0 && StartTime.isValid())
815 else if (RecordId > 0)
819 query.
prepare(
"SELECT recordedid FROM recorded "
820 " WHERE recordid = :RECORDID "
821 " ORDER BY starttime DESC LIMIT 1");
830 recId = query.
value(0).toInt();
837 throw QString(
"Recorded ID or Channel ID and StartTime or RecordId are invalid.");
855 "RescheduleRecordings");
867 if (ChanId > 0 || StartTime.isValid())
868 throw QString(
"ERROR RecordedId param cannot be used with ChanId or StartTime.");
872 if (!StartTime.isValid())
873 throw QString(
"ERROR ChanId param requires a valid StartTime.");
877 throw QString(
"ERROR RecordedId or (ChanId and StartTime) required.");
884 throw QString(
"ERROR RecordedId %1 not found").arg(RecordedId);
890 if (progInfo ==
nullptr)
891 throw QString(
"ERROR Guide data for Chanid %1 at StartTime %2 not found")
892 .arg(ChanId).arg(StartTime.toString());
906 const QDateTime &StartTime,
911 if ((RecordedId <= 0) &&
912 (chanid <= 0 || !StartTime.isValid()))
913 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
937 const QDateTime &StartTime,
938 const QString &offsettype )
940 if ((RecordedId <= 0) &&
941 (chanid <= 0 || !StartTime.isValid()))
942 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
955 if (offsettype.toLower() ==
"position"){
961 if (offsettype.toLower() ==
"duration"){
979 const QDateTime &StartTime,
980 const QString &offsettype )
982 if (RecordedId == -1)
985 if ((RecordedId <= 0) &&
986 (chanid <= 0 || !StartTime.isValid()))
987 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1000 if (offsettype.toLower() ==
"position"){
1006 if (offsettype.toLower() ==
"duration"){
1021 const QDateTime &StartTime,
1022 const QString &offsettype,
1027 if ((RecordedId <= 0) &&
1028 (chanid <= 0 || !StartTime.isValid()))
1029 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1032 throw QString(
"Offset must be >= 0.");
1039 uint64_t position = 0;
1041 if (offsettype.toLower() ==
"position"){
1045 else if (offsettype.toLower() ==
"duration"){
1065 const QDateTime &StartTime,
1066 const QString &offsettype,
1071 if ((RecordedId <= 0) &&
1072 (chanid <= 0 || !StartTime.isValid()))
1073 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1076 throw QString(
"Offset must be >= 0.");
1083 uint64_t position = 0;
1085 if (offsettype.toLower() ==
"position"){
1089 else if (offsettype.toLower() ==
"duration"){
1103 const QDateTime &StartTime,
1104 const QString &offsettype,
1108 if ((RecordedId <= 0) &&
1109 (chanid <= 0 || !StartTime.isValid()))
1110 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1119 if (offsettype.toLower() ==
"position")
1121 else if (offsettype.toLower() ==
"duration")
1137 const QDateTime &StartTime,
1138 const QString &offsettype,
1142 if ((RecordedId <= 0) &&
1143 (chanid <= 0 || !StartTime.isValid()))
1144 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1153 if (offsettype.toLower() ==
"position")
1155 else if (offsettype.toLower() ==
"duration")
1170 const QString &offsettype )
1173 if (RecordedId <= 0)
1174 throw QString(
"Recorded ID appears invalid.");
1180 if (offsettype.toLower() ==
"bytes")
1182 else if (offsettype.toLower() ==
"duration")
1187 throw QString(
"Type must be 'BYTES' or 'DURATION'.");
1205 throw QString(
"Invalid RecordedId %1").arg(RecordedId);
1207 QVector<ProgramInfo::MarkupEntry> mapMark;
1208 QVector<ProgramInfo::MarkupEntry> mapSeek;
1213 for (
const auto& entry : std::as_const(mapMark))
1215 V2Markup *pMarkup = pMarkupList->AddNewMarkup();
1217 pMarkup->setType(typestr);
1218 pMarkup->setFrame(entry.frame);
1219 if (entry.isDataNull)
1220 pMarkup->setData(
"NULL");
1222 pMarkup->setData(QString::number(entry.data));
1224 for (
const auto& entry : std::as_const(mapSeek))
1226 V2Markup *pSeek = pMarkupList->AddNewSeek();
1228 pSeek->setType(typestr);
1229 pSeek->setFrame(entry.frame);
1230 if (entry.isDataNull)
1231 pSeek->setData(
"NULL");
1233 pSeek->setData(QString::number(entry.data));
1250 throw QString(
"Invalid RecordedId %1").arg(RecordedId);
1252 QVector<ProgramInfo::MarkupEntry> mapMark;
1253 QVector<ProgramInfo::MarkupEntry> mapSeek;
1255 QJsonDocument doc = QJsonDocument::fromJson(MarkupList.toUtf8());
1256 QJsonObject markuplist = doc.object();
1258 QJsonArray marks = markuplist[
"Mark"].toArray();
1259 for (
const auto & m : std::as_const(marks))
1261 QJsonObject markup = m.toObject();
1264 QString typestr = markup.value(
"Type").toString(
"");
1266 entry.
frame = markup.value(
"Frame").toVariant()
1267 .toString().toLongLong();
1268 QString data = markup.value(
"Data").toString(
"NULL");
1271 entry.
data = data.toLongLong();
1273 mapMark.append(entry);
1276 QJsonArray seeks = markuplist[
"Seek"].toArray();
1277 for (
const auto & m : std::as_const(seeks))
1279 QJsonObject markup = m.toObject();
1282 QString typestr = markup.value(
"Type").toString(
"");
1284 entry.
frame = markup.value(
"Frame").toVariant().toString().toLongLong();
1285 QString data = markup.value(
"Data").toString(
"NULL");
1288 entry.
data = data.toLongLong();
1290 mapSeek.append(entry);
1318 for (
const auto & inputInfo : std::as_const(inputInfoList))
1320 V2Input *input = pList->AddNewInput();
1334 if (UsedBy.compare(
"recorded",Qt::CaseInsensitive) == 0)
1335 query.
prepare(
"SELECT DISTINCT recgroup FROM recorded "
1336 "ORDER BY recgroup");
1337 else if (UsedBy.compare(
"schedule",Qt::CaseInsensitive) == 0)
1338 query.
prepare(
"SELECT DISTINCT recgroup FROM record "
1339 "ORDER BY recgroup");
1341 query.
prepare(
"SELECT recgroup FROM recgroups WHERE recgroup <> 'Deleted' "
1342 "ORDER BY recgroup");
1351 while (query.
next())
1352 result << query.
value(0).toString();
1366 query.
prepare(
"SELECT DISTINCT category FROM recorded ORDER BY category");
1368 query.
prepare(
"SELECT DISTINCT category FROM program ORDER BY category");
1377 while (query.
next())
1378 result << query.
value(0).toString();
1407 query.
prepare(
"SELECT name, titlematch, skipahead, skipback, timestretch, jump "
1408 "FROM playgroup WHERE name = :NAME ");
1415 playGroup->setName(query.
value(0).toString());
1416 playGroup->setTitleMatch(query.
value(1).toString());
1417 playGroup->setSkipAhead(query.
value(2).toInt());
1418 playGroup->setSkipBack(query.
value(3).toInt());
1419 playGroup->setTimeStretch(query.
value(4).toInt());
1420 playGroup->setJump(query.
value(5).toInt());
1424 throw QString(
"Play Group Not Found.");
1433 if (
Name.compare(
"Default", Qt::CaseInsensitive) == 0)
1434 throw QString(
"ERROR: Cannot delete Default entry");
1436 query.
prepare(
"DELETE FROM playgroup "
1437 "WHERE name = :NAME");
1441 return query.
exec();
1453 query.
prepare(
"INSERT INTO playgroup "
1454 "(name, titlematch, skipahead, skipback, timestretch, jump) "
1455 " VALUES(:NAME, :TITLEMATCH, :SKIPAHEAD, :SKIPBACK, :TIMESTRETCH, :JUMP)");
1463 return query.
exec();
1474 throw QString(
"ERROR: Name is not specified");
1478 QString sql =
"UPDATE playgroup SET ";
1481 sql.append(
" titlematch = :TITLEMATCH ");
1488 sql.append(
" skipahead = :SKIPAHEAD ");
1495 sql.append(
" skipback = :SKIPBACK ");
1502 sql.append(
" timestretch = :TIMESTRETCH ");
1509 sql.append(
" jump = :JUMP ");
1514 sql.append(
" WHERE name = :NAME ");
1544 query.
prepare(
"SELECT filterid, description, newruledefault "
1545 "FROM recordfilter ORDER BY filterid");
1549 while (query.
next())
1552 ruleFilter->setId(query.
value(0).toInt());
1553 ruleFilter->setDescription(QObject::tr(query.
value(1).toString()
1554 .toUtf8().constData()));
1569 QString querystr =
"SELECT DISTINCT title FROM recorded "
1570 "WHERE deletepending = 0";
1572 if (!RecGroup.isEmpty())
1573 querystr +=
" AND recgroup = :RECGROUP";
1575 querystr +=
" AND recgroup != 'Deleted'";
1577 querystr +=
" ORDER BY title";
1581 if (!RecGroup.isEmpty())
1591 while (query.
next())
1592 result << query.
value(0).toString();
1605 QString querystr = QString(
1606 "SELECT title, inetref, count(title) as count "
1607 " FROM recorded AS r "
1608 " JOIN recgroups AS g ON r.recgroupid = g.recgroupid "
1609 " WHERE g.recgroup NOT IN ('Deleted', 'LiveTV') "
1610 " AND r.deletepending = 0 "
1611 " GROUP BY title, inetref "
1623 while (query.
next())
1625 V2TitleInfo *pTitleInfo = pTitleInfos->AddNewTitleInfo();
1627 pTitleInfo->setTitle(query.
value(0).toString());
1628 pTitleInfo->setInetref(query.
value(1).toString());
1629 pTitleInfo->setCount(query.
value(2).toInt());
1639 const QString &Sort )
1650 pPrograms->setStartIndex ( nStartIndex );
1651 pPrograms->setCount ( nCount );
1652 pPrograms->setTotalAvailable( size );
1654 pPrograms->setVersion ( MYTH_BINARY_VERSION );
1655 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1665 const QString &Sort,
1666 const QString &RecGroup )
1672 QMetaEnum meta = QMetaEnum::fromType<RecStatus::Type>();
1674 nRecStatus = meta.keyToValue(
RecStatus.toLocal8Bit(), &ok);
1692 pPrograms->setStartIndex ( nStartIndex );
1693 pPrograms->setCount ( nCount );
1694 pPrograms->setTotalAvailable( size );
1696 pPrograms->setVersion ( MYTH_BINARY_VERSION );
1697 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1703 const QString& sTitle,
1704 const QString& sSubtitle,
1705 const QString& sDescription,
1706 const QString& sCategory,
1707 const QDateTime& StartTime,
1708 const QDateTime& EndTime,
1709 const QString& sSeriesId,
1710 const QString& sProgramId,
1712 const QString& sStation,
1719 const QString& sInetref,
1721 QString sSearchType,
1723 uint nPreferredInput,
1726 const QDateTime& LastRecorded,
1731 QString sRecProfile,
1733 QString sStorageGroup,
1739 bool bAutoTranscode,
1740 bool bAutoMetaLookup,
1746 const QString& AutoExtend)
1748 QDateTime recstartts = StartTime.toUTC();
1749 QDateTime recendts = EndTime.toUTC();
1750 QDateTime lastrects = LastRecorded.toUTC();
1754 if (sType.isEmpty())
1757 if (sSearchType.isEmpty())
1758 sSearchType =
"none";
1760 if (sDupMethod.isEmpty())
1761 sDupMethod =
"subtitleanddescription";
1763 if (sDupIn.isEmpty())
1783 if (sRecProfile.isEmpty())
1784 sRecProfile =
"Default";
1786 if (sRecGroup.isEmpty())
1787 sRecGroup =
"Default";
1789 if (sStorageGroup.isEmpty())
1790 sStorageGroup =
"Default";
1792 if (sPlayGroup.isEmpty())
1793 sPlayGroup =
"Default";
1851 bool success = rule.
Save();
1853 throw QString(
"DATABASE ERROR: Check for duplicate recording rule");
1861 const QString& sTitle,
1862 const QString& sSubtitle,
1863 const QString& sDescription,
1864 const QString& sCategory,
1865 const QDateTime& StartTime,
1866 const QDateTime& EndTime,
1867 const QString& sSeriesId,
1868 const QString& sProgramId,
1870 const QString& sStation,
1876 const QString& sInetref,
1878 QString sSearchType,
1880 uint nPreferredInput,
1887 QString sRecProfile,
1889 QString sStorageGroup,
1895 bool bAutoTranscode,
1896 bool bAutoMetaLookup,
1902 const QString& AutoExtend)
1904 if (nRecordId == 0 )
1905 throw QString(
"Record ID is invalid.");
1912 throw QString(
"Record ID does not exist.");
1914 QDateTime recstartts = StartTime.toUTC();
1915 QDateTime recendts = EndTime.toUTC();
1918 if (sType.isEmpty())
1921 if (sSearchType.isEmpty())
1922 sSearchType =
"none";
1924 if (sDupMethod.isEmpty())
1925 sDupMethod =
"subtitleanddescription";
1927 if (sDupIn.isEmpty())
1938 if (sRecProfile.isEmpty())
1939 sRecProfile =
"Default";
1941 if (sRecGroup.isEmpty())
1942 sRecGroup =
"Default";
1944 if (sStorageGroup.isEmpty())
1945 sStorageGroup =
"Default";
1947 if (sPlayGroup.isEmpty())
1948 sPlayGroup =
"Default";
1950 if (!sTitle.isEmpty())
1953 if (!sSubtitle.isEmpty())
1956 if(!sDescription.isEmpty())
1959 if (!sCategory.isEmpty())
1962 if (!sSeriesId.isEmpty())
1965 if (!sProgramId.isEmpty())
1970 if (!sStation.isEmpty())
2019 if (!AutoExtend.isEmpty())
2026 bool bResult = pRule.
Save();
2033 bool bResult =
false;
2035 if (nRecordId == 0 )
2036 throw QString(
"Record ID does not exist.");
2041 bResult = pRule.
Delete();
2049 bool bResult =
true;
2051 if (nChanId <= 0 || !dStartTime.isValid())
2052 throw QString(
"Program does not exist.");
2057 throw QString(
"Program does not exist.");
2078 const QString &Sort,
2082 if (Sort.toLower() ==
"lastrecorded")
2084 else if (Sort.toLower() ==
"nextrecording")
2086 else if (Sort.toLower() ==
"title")
2088 else if (Sort.toLower() ==
"priority")
2090 else if (Sort.toLower() ==
"type")
2104 nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (
int)recList.size() ) : 0;
2105 nCount = (nCount > 0) ? std::min( nCount, (
int)recList.size() ) : recList.size();
2106 int nEndIndex = std::min((nStartIndex + nCount), (
int)recList.size() );
2108 for(
int n = nStartIndex; n < nEndIndex; n++)
2112 if (
info !=
nullptr)
2114 V2RecRule *pRecRule = pRecRules->AddNewRecRule();
2122 pRecRules->setStartIndex ( nStartIndex );
2123 pRecRules->setCount ( nCount );
2124 pRecRules->setTotalAvailable( recList.size() );
2126 pRecRules->setVersion ( MYTH_BINARY_VERSION );
2127 pRecRules->setProtoVer ( MYTH_PROTO_VERSION );
2129 while (!recList.empty())
2131 delete recList.back();
2139 const QString& sTemplate,
2142 const QDateTime& StartTime,
2143 bool bMakeOverride )
2146 QDateTime dStartTime = StartTime.toUTC();
2152 throw QString(
"Record ID does not exist.");
2154 else if (!sTemplate.isEmpty())
2157 throw QString(
"Template does not exist.");
2159 else if (nRecordedId > 0)
2164 throw QString(
"Recording does not exist");
2166 else if (nChanId > 0 && dStartTime.isValid())
2173 throw QString(
"Program does not exist.");
2182 throw QString(
"Invalid request.");
2193 bool bResult =
false;
2195 if (nRecordId == 0 )
2196 throw QString(
"Record ID appears invalid.");
2205 bResult = pRule.
Save();
2213 bool bResult =
false;
2215 if (nRecordId == 0 )
2216 throw QString(
"Record ID appears invalid.");
2225 bResult = pRule.
Save();
2244 uint recordedid = 0;
2255 QMetaEnum meta = QMetaEnum::fromType<RecStatus::Type>();
2257 int value = meta.keyToValue(
RecStatus.toLocal8Bit(), &ok);
2269 const QDateTime &StartTime)
2272 QMetaEnum meta = QMetaEnum::fromType<RecStatus::Type>();
2274 int value = meta.keyToValue(
RecStatus.toLocal8Bit(), &ok);
2289 auto enumType =
static_cast<RecordingType>(recType.toInt(&ok, 10));
2299 auto enumType =
static_cast<RecordingType>(recType.toInt(&ok, 10));
2337 const QString &sJobName,
2340 QDateTime JobStartTime,
2341 QString sRemoteHost,
2349 LOG(VB_GENERAL, LOG_ERR,
"JobName and RecordedId are required.");
2353 if (sRemoteHost.isEmpty())
2366 if ( sAction ==
"Remove")
2370 LOG(VB_GENERAL, LOG_ERR,
"For Remove, a valid JobId is required.");
2381 if ( sAction !=
"Add")
2383 LOG(VB_GENERAL, LOG_ERR, QString(
"Illegal Action name '%1'. Use: Add, "
2384 "or Remove").arg(sAction));
2391 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 hasn't been defined.")
2397 sRemoteHost,
false))
2399 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Note: %1 hasn't been allowed on host %2.")
2400 .arg(sJobName, sRemoteHost));
2404 if (!JobStartTime.isValid())
2405 JobStartTime = QDateTime::currentDateTime();
2410 if (sJobArgs.isNull())
2417 QString(
"Dvr/ManageJobQueue"),
2421 JobStartTime.toUTC());
2425 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 job wasn't queued because of a "
2426 "database error or because it was "
2427 "already running/stopping etc.")
2443 long BookmarkOffset,
2444 const QString &BookmarkOffsetType,
2446 const QString &Description,
2448 const QString &Inetref,
2449 long LastPlayOffset,
2450 const QString &LastPlayOffsetType,
2451 QDate OriginalAirDate,
2455 const QString &SubTitle,
2456 const QString &Title,
2458 const QString &RecGroup )
2463 LOG(VB_GENERAL, LOG_ERR,
"No RecordedId, or no parameters to change.");
2470 if (!ri.GetChanID())
2479 uint64_t position =0;
2481 if (BookmarkOffsetType.toLower() ==
"position")
2483 if (!ri.QueryPositionKeyFrame(&position, BookmarkOffset,
true))
2486 else if (BookmarkOffsetType.toLower() ==
"duration")
2488 if (!ri.QueryDurationKeyFrame(&position, BookmarkOffset,
true))
2493 position = BookmarkOffset;
2496 ri.SaveBookmark(position);
2500 pi.SaveVideoProperties(VID_DAMAGED, Damaged ? VID_DAMAGED : 0);
2507 QString tmp_description;
2508 QString tmp_subtitle;
2512 tmp_description = Description;
2514 tmp_description = ri.GetDescription();
2517 tmp_subtitle = SubTitle;
2519 tmp_subtitle = ri.GetSubtitle();
2524 tmp_title = ri.GetTitle();
2526 ri.ApplyRecordRecTitleChange(tmp_title, tmp_subtitle, tmp_description);
2532 int tmp_episode = 0;
2536 tmp_episode = Episode;
2538 tmp_episode = ri.GetEpisode();
2541 tmp_season = Season;
2543 tmp_season = ri.GetSeason();
2545 pi.SaveSeasonEpisode(tmp_season, tmp_episode);
2549 pi.SaveInetRef(Inetref);
2554 if (LastPlayOffset < 0)
2555 throw QString(
"LastPlayOffset must be >= 0.");
2557 uint64_t position = LastPlayOffset;
2562 if (LastPlayOffsetType.toLower() ==
"position")
2564 if (!ri.QueryPositionKeyFrame(&position, LastPlayOffset, isend))
2567 else if (LastPlayOffsetType.toLower() ==
"duration")
2569 if (!ri.QueryDurationKeyFrame(&position, LastPlayOffset, isend))
2574 ri.SaveLastPlayPos(position);
2583 if (!OriginalAirDate.isValid() && !OriginalAirDate.isNull())
2585 LOG(VB_GENERAL, LOG_ERR,
"Need valid OriginalAirDate yyyy-mm-dd.");
2588 ri.ApplyOriginalAirDateChange(OriginalAirDate);
2592 pi.SavePreserve(Preserve);
2598 LOG(VB_GENERAL, LOG_ERR,
"Recording stars can be 0 to 10.");
2601 ri.ApplyStarsChange(
Stars * 0.1F);
2605 pi.SaveWatched(Watched);
2608 ri.ApplyRecordRecGroupChange(RecGroup);
2620 QString sql(
"SELECT priorityname, recpriority, selectclause "
2621 "FROM powerpriority ");
2623 if (!PriorityName.isEmpty())
2624 sql.append(
" WHERE priorityname = :NAME ");
2628 if (!PriorityName.isEmpty())
2633 while (query.
next())
2636 pRec->setPriorityName(query.
value(0).toString());
2637 pRec->setRecPriority(query.
value(1).toInt());
2638 pRec->setSelectClause(query.
value(2).toString());
2643 throw (QString(
"Error accessing powerpriority table"));
2651 if (PriorityName.isEmpty())
2655 query.
prepare(
"DELETE FROM powerpriority WHERE priorityname = :PRIORITYNAME");
2656 query.
bindValue(
":PRIORITYNAME", PriorityName);
2658 return query.
exec();
2663 const QString & SelectClause )
2665 if (PriorityName.isEmpty())
2666 throw QString(
"ERROR: PriorityName is not specified");
2667 if (SelectClause.isEmpty())
2668 throw QString(
"ERROR: SelectClause is required");
2670 if (! msg.isEmpty() )
2673 query.
prepare(
"INSERT INTO powerpriority "
2674 " (priorityname, recpriority, selectclause) "
2675 " VALUES(:PRIORITYNAME, :RECPRIORITY, :SELECTCLAUSE) ");
2676 query.
bindValue(
":PRIORITYNAME", PriorityName);
2677 query.
bindValue(
":RECPRIORITY", RecPriority);
2678 query.
bindValue(
":SELECTCLAUSE", SelectClause);
2680 throw(query.
lastError().databaseText());
2686 const QString & SelectClause )
2688 if (PriorityName.isEmpty())
2689 throw QString(
"ERROR: PriorityName is not specified");
2691 throw QString(
"ERROR: RecPriority or SelectClause is required");
2696 if (! msg.isEmpty() )
2701 QString sql(
"UPDATE powerpriority SET ");
2704 sql.append(
" recpriority = :RECPRIORITY ");
2711 sql.append(
" selectclause = :SELECTCLAUSE ");
2713 sql.append(
" where priorityname = :PRIORITYNAME ");
2715 query.
bindValue(
":PRIORITYNAME", PriorityName);
2717 query.
bindValue(
":RECPRIORITY", RecPriority);
2719 query.
bindValue(
":SELECTCLAUSE", SelectClause);
2721 throw(query.
lastError().databaseText());
2728 QString sql = QString(
"SELECT (%1) FROM (recordmatch, record, "
2729 "program, channel, capturecard, "
2730 "oldrecorded) WHERE NULL").arg(SelectClause);
2733 int i = sql.indexOf(
"RECTABLE");
2735 sql = sql.replace(i, strlen(
"RECTABLE"),
"record");
2743 msg = tr(
"An error was found when checking") +
":\n\n";
2745 msg +=
"\n\n" + tr(
"The database error was") +
":\n";
2746 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)