MythTV  master
v2dvr.cpp
Go to the documentation of this file.
1 // Program Name: v2dvr.cpp
3 // Created : Mar. 7, 2011
4 //
5 // Copyright (c) 2011 David Blain <dblain@mythtv.org>
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //
25 
26 // MythTV
30 #include "libmythbase/mythversion.h"
33 #include "libmythtv/cardutil.h"
34 #include "libmythtv/channelutil.h"
35 #include "libmythtv/jobqueue.h"
36 #include "libmythtv/playgroup.h"
37 #include "libmythtv/programdata.h"
38 #include "libmythtv/tv_rec.h"
39 
40 // MythBackend
41 #include "autoexpire.h"
42 #include "backendcontext.h"
43 #include "encoderlink.h"
44 #include "scheduler.h"
45 #include "v2dvr.h"
46 #include "v2serviceUtil.h"
47 #include "v2titleInfoList.h"
48 
49 // This will be initialised in a thread safe manner on first use
51  (DVR_HANDLE, V2Dvr::staticMetaObject, &V2Dvr::RegisterCustomTypes))
52 
54 {
55  qRegisterMetaType<V2ProgramList*>("V2ProgramList");
56  qRegisterMetaType<V2Program*>("V2Program");
57  qRegisterMetaType<V2CutList*>("V2CutList");
58  qRegisterMetaType<V2Cutting*>("V2Cutting");
59  qRegisterMetaType<V2MarkupList*>("V2MarkupList");
60  qRegisterMetaType<V2Markup*>("V2Markup");
61  qRegisterMetaType<V2EncoderList*>("V2EncoderList");
62  qRegisterMetaType<V2Encoder*>("V2Encoder");
63  qRegisterMetaType<V2InputList*>("V2InputList");
64  qRegisterMetaType<V2Input*>("V2Input");
65  qRegisterMetaType<V2RecRuleFilterList*>("V2RecRuleFilterList");
66  qRegisterMetaType<V2RecRuleFilter*>("V2RecRuleFilter");
67  qRegisterMetaType<V2TitleInfoList*>("V2TitleInfoList");
68  qRegisterMetaType<V2TitleInfo*>("V2TitleInfo");
69  qRegisterMetaType<V2RecRule*>("V2RecRule");
70  qRegisterMetaType<V2RecRuleList*>("V2RecRuleList");
71  qRegisterMetaType<V2ChannelInfo*>("V2ChannelInfo");
72  qRegisterMetaType<V2RecordingInfo*>("V2RecordingInfo");
73  qRegisterMetaType<V2ArtworkInfoList*>("V2ArtworkInfoList");
74  qRegisterMetaType<V2ArtworkInfo*>("V2ArtworkInfo");
75  qRegisterMetaType<V2CastMemberList*>("V2CastMemberList");
76  qRegisterMetaType<V2CastMember*>("V2CastMember");
77 }
78 
80  : MythHTTPService(s_service)
81 {
82 }
83 
85  int nCount )
86 {
87  pginfolist_t infoList;
88 
89  if (gExpirer)
90  gExpirer->GetAllExpiring( infoList );
91 
92  // ----------------------------------------------------------------------
93  // Build Response
94  // ----------------------------------------------------------------------
95 
96  auto *pPrograms = new V2ProgramList();
97 
98  nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (int)infoList.size() ) : 0;
99  nCount = (nCount > 0) ? std::min( nCount, (int)infoList.size() ) : infoList.size();
100  int nEndIndex = std::min((nStartIndex + nCount), (int)infoList.size() );
101 
102  for( int n = nStartIndex; n < nEndIndex; n++)
103  {
104  ProgramInfo *pInfo = infoList[ n ];
105 
106  if (pInfo != nullptr)
107  {
108  V2Program *pProgram = pPrograms->AddNewProgram();
109 
110  V2FillProgramInfo( pProgram, pInfo, true );
111 
112  delete pInfo;
113  }
114  }
115 
116  // ----------------------------------------------------------------------
117 
118  pPrograms->setStartIndex ( nStartIndex );
119  pPrograms->setCount ( nCount );
120  pPrograms->setTotalAvailable( infoList.size() );
121  pPrograms->setAsOf ( MythDate::current() );
122  pPrograms->setVersion ( MYTH_BINARY_VERSION );
123  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
124 
125  return pPrograms;
126 }
127 
129  int nStartIndex,
130  int nCount,
131  const QString &sTitleRegEx,
132  const QString &sRecGroup,
133  const QString &sStorageGroup,
134  const QString &sCategory,
135  const QString &sSort,
136  bool bIgnoreLiveTV,
137  bool bIgnoreDeleted,
138  bool bIncChannel,
139  bool bDetails,
140  bool bIncCast,
141  bool bIncArtWork,
142  bool bIncRecording
143  )
144 {
145  if (!HAS_PARAMv2("IncChannel"))
146  bIncChannel = true;
147 
148  if (!HAS_PARAMv2("Details"))
149  bDetails = true;
150 
151  if (!HAS_PARAMv2("IncCast"))
152  bIncCast = true;
153 
154  if (!HAS_PARAMv2("IncArtwork"))
155  bIncArtWork = true;
156 
157  if (!HAS_PARAMv2("IncRecording"))
158  bIncRecording = true;
159 
160  QMap< QString, ProgramInfo* > recMap;
161 
162  if (gCoreContext->GetScheduler())
163  recMap = gCoreContext->GetScheduler()->GetRecording();
164 
165  QMap< QString, uint32_t > inUseMap = ProgramInfo::QueryInUseMap();
166  QMap< QString, bool > isJobRunning= ProgramInfo::QueryJobsRunning(JOB_COMMFLAG);
167 
168  ProgramList progList;
169 
170  int desc = 1;
171  if (bDescending)
172  desc = -1;
173 
174  if (bIgnoreLiveTV && (sRecGroup == "LiveTV"))
175  {
176  bIgnoreLiveTV = false;
177  LOG(VB_GENERAL, LOG_ERR, QString("Setting Ignore%1=false because RecGroup=%1")
178  .arg(sRecGroup));
179  }
180 
181  if (bIgnoreDeleted && (sRecGroup == "Deleted"))
182  {
183  bIgnoreDeleted = false;
184  LOG(VB_GENERAL, LOG_ERR, QString("Setting Ignore%1=false because RecGroup=%1")
185  .arg(sRecGroup));
186  }
187 
188  LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, desc,
189  sSort, bIgnoreLiveTV, bIgnoreDeleted );
190 
191  QMap< QString, ProgramInfo* >::iterator mit = recMap.begin();
192 
193  for (; mit != recMap.end(); mit = recMap.erase(mit))
194  delete *mit;
195 
196  // ----------------------------------------------------------------------
197  // Build Response
198  // ----------------------------------------------------------------------
199 
200  auto *pPrograms = new V2ProgramList();
201 
202  int nAvailable = 0;
203 
204  int nMax = (nCount > 0) ? nCount : progList.size();
205 
206  nAvailable = 0;
207  nCount = 0;
208 
209  QRegularExpression rTitleRegEx
210  { sTitleRegEx, QRegularExpression::CaseInsensitiveOption };
211 
212  for (auto *pInfo : progList)
213  {
214  if (pInfo->IsDeletePending() ||
215  (!sTitleRegEx.isEmpty() && !pInfo->GetTitle().contains(rTitleRegEx)) ||
216  (!sRecGroup.isEmpty() && sRecGroup != pInfo->GetRecordingGroup()) ||
217  (!sStorageGroup.isEmpty() && sStorageGroup != pInfo->GetStorageGroup()) ||
218  (!sCategory.isEmpty() && sCategory != pInfo->GetCategory()))
219  continue;
220 
221  if ((nAvailable < nStartIndex) ||
222  (nCount >= nMax))
223  {
224  ++nAvailable;
225  continue;
226  }
227 
228  ++nAvailable;
229  ++nCount;
230 
231  V2Program *pProgram = pPrograms->AddNewProgram();
232  V2FillProgramInfo( pProgram, pInfo, bIncChannel, bDetails, bIncCast, bIncArtWork, bIncRecording );
233  }
234 
235  // ----------------------------------------------------------------------
236 
237  pPrograms->setStartIndex ( nStartIndex );
238  pPrograms->setCount ( nCount );
239  pPrograms->setTotalAvailable( nAvailable );
240  pPrograms->setAsOf ( MythDate::current() );
241  pPrograms->setVersion ( MYTH_BINARY_VERSION );
242  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
243 
244  return pPrograms;
245 }
246 
248 //
250 
252  int nStartIndex,
253  int nCount,
254  const QDateTime &sStartTime,
255  const QDateTime &sEndTime,
256  const QString &sTitle,
257  const QString &sSeriesId,
258  int nRecordId,
259  const QString &sSort)
260 {
261  if (!sStartTime.isNull() && !sStartTime.isValid())
262  throw QString("StartTime is invalid");
263 
264  if (!sEndTime.isNull() && !sEndTime.isValid())
265  throw QString("EndTime is invalid");
266 
267  const QDateTime& dtStartTime = sStartTime;
268  const QDateTime& dtEndTime = sEndTime;
269 
270  if (!sEndTime.isNull() && dtEndTime < dtStartTime)
271  throw QString("EndTime is before StartTime");
272 
273  // ----------------------------------------------------------------------
274  // Build SQL statement for Program Listing
275  // ----------------------------------------------------------------------
276 
277  ProgramList progList;
278  MSqlBindings bindings;
279  QString sSQL;
280 
281  if (!dtStartTime.isNull())
282  {
283  sSQL += " AND endtime >= :StartDate ";
284  bindings[":StartDate"] = dtStartTime;
285  }
286 
287  if (!dtEndTime.isNull())
288  {
289  sSQL += " AND starttime <= :EndDate ";
290  bindings[":EndDate"] = dtEndTime;
291  }
292 
293  QStringList clause;
294 
295  if (nRecordId > 0)
296  {
297  clause << "recordid = :RecordId";
298  bindings[":RecordId"] = nRecordId;
299  }
300 
301  if (!sTitle.isEmpty())
302  {
303  clause << "title = :Title";
304  bindings[":Title"] = sTitle;
305  }
306 
307  if (!sSeriesId.isEmpty())
308  {
309  clause << "seriesid = :SeriesId";
310  bindings[":SeriesId"] = sSeriesId;
311  }
312 
313  if (!clause.isEmpty())
314  {
315  sSQL += QString(" AND (%1) ").arg(clause.join(" OR "));
316  }
317 
318  if (sSort == "starttime")
319  sSQL += "ORDER BY starttime "; // NOLINT(bugprone-branch-clone)
320  else if (sSort == "title")
321  sSQL += "ORDER BY title ";
322  else
323  sSQL += "ORDER BY starttime ";
324 
325  if (bDescending)
326  sSQL += "DESC ";
327  else
328  sSQL += "ASC ";
329 
330  uint nTotalAvailable = (nStartIndex == 0) ? 1 : 0;
331  LoadFromOldRecorded( progList, sSQL, bindings,
332  (uint)nStartIndex, (uint)nCount, nTotalAvailable );
333 
334  // ----------------------------------------------------------------------
335  // Build Response
336  // ----------------------------------------------------------------------
337 
338  auto *pPrograms = new V2ProgramList();
339 
340  nCount = (int)progList.size();
341  int nEndIndex = (int)progList.size();
342 
343  for( int n = 0; n < nEndIndex; n++)
344  {
345  ProgramInfo *pInfo = progList[ n ];
346 
347  V2Program *pProgram = pPrograms->AddNewProgram();
348 
349  V2FillProgramInfo( pProgram, pInfo, true );
350  }
351 
352  // ----------------------------------------------------------------------
353 
354  pPrograms->setStartIndex ( nStartIndex );
355  pPrograms->setCount ( nCount );
356  pPrograms->setTotalAvailable( nTotalAvailable );
357  pPrograms->setAsOf ( MythDate::current() );
358  pPrograms->setVersion ( MYTH_BINARY_VERSION );
359  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
360 
361  return pPrograms;
362 }
363 
365 //
367 
369  int chanid, const QDateTime &StartTime)
370 {
371  if ((RecordedId <= 0) &&
372  (chanid <= 0 || !StartTime.isValid()))
373  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
374 
375  // TODO Should use RecordingInfo
376  ProgramInfo pi;
377  if (RecordedId > 0)
378  pi = ProgramInfo(RecordedId);
379  else
380  pi = ProgramInfo(chanid, StartTime.toUTC());
381 
382  auto *pProgram = new V2Program();
383  V2FillProgramInfo( pProgram, &pi, true );
384 
385  return pProgram;
386 }
387 
389 //
391 
392 bool V2Dvr::AddRecordedCredits(int RecordedId, const QString & Cast)
393 {
394  QJsonDocument jsonDoc = QJsonDocument::fromJson(Cast.toUtf8());
395  // Verify the corresponding recording exists
396  RecordingInfo ri(RecordedId);
397  if (!ri.HasPathname())
398  throw QString("AddRecordedCredits: recordedid %1 does "
399  "not exist.").arg(RecordedId);
400 
401  DBCredits* credits = V2jsonCastToCredits(jsonDoc.object());
402  if (credits == nullptr)
403  throw QString("AddRecordedCredits: Failed to parse cast from json.");
404 
405  MSqlQuery query(MSqlQuery::InitCon());
406  for (auto & person : *credits)
407  {
408  if (!person.InsertDB(query, ri.GetChanID(),
409  ri.GetScheduledStartTime(), true))
410  throw QString("AddRecordedCredits: Failed to add credit "
411  "%1 to DB").arg(person.toString());
412  }
413 
414  return true;
415 }
416 
418 //
420 
421 int V2Dvr::AddRecordedProgram(const QString &Program)
422 {
423  QJsonDocument doc = QJsonDocument::fromJson(Program.toUtf8());
424  QJsonObject program = doc.object();
425  QJsonObject channel = program["Channel"].toObject();
426  QJsonObject recording = program["Recording"].toObject();
427  QJsonObject cast = program["Cast"].toObject();
428 
429  auto *pi = new ProgInfo();
430  int chanid = channel.value("ChanId").toVariant().toString().toUInt();
431 
432  QString hostname = program["HostName"].toString("");
433 
434  if (ChannelUtil::GetChanNum(chanid).isEmpty())
435  throw QString("AddRecordedProgram: chanid %1 does "
436  "not exist.").arg(chanid);
437 
438  pi->m_title = program.value("Title").toString("");
439  pi->m_subtitle = program.value("SubTitle").toString("");
440  pi->m_description = program.value("Description").toString("");
441  pi->m_category = program.value("Category").toString("");
442  pi->m_starttime = QDateTime::fromString(program.value("StartTime")
443  .toString(""), Qt::ISODate);
444  pi->m_endtime = QDateTime::fromString(program.value("EndTime")
445  .toString(""), Qt::ISODate);
446  pi->m_originalairdate = QDate::fromString(program.value("Airdate").toString(),
447  Qt::ISODate);
448  pi->m_airdate = pi->m_originalairdate.year();
449  pi->m_partnumber = program.value("PartNumber").toString("0").toUInt();
450  pi->m_parttotal = program.value("PartTotal").toString("0").toUInt();
451  pi->m_syndicatedepisodenumber = "";
452  pi->m_subtitleType = ProgramInfo::SubtitleTypesFromNames
453  (program.value("SubPropNames").toString(""));
454  pi->m_audioProps = ProgramInfo::AudioPropertiesFromNames
455  (program.value("AudioPropNames").toString(""));
456  pi->m_videoProps = ProgramInfo::VideoPropertiesFromNames
457  (program.value("VideoPropNames").toString(""));
458  pi->m_stars = program.value("Stars").toVariant().toString().toFloat();
459  pi->m_categoryType = string_to_myth_category_type(program.value("CatType").toString(""));
460  pi->m_seriesId = program.value("SeriesId").toString("");
461  pi->m_programId = program.value("ProgramId").toString("");
462  pi->m_inetref = program.value("Inetref").toString("");
463  pi->m_previouslyshown = false;
464  pi->m_listingsource = 0;
465 // pi->m_ratings =
466 // pi->m_genres =
467  pi->m_season = program.value("Season").toVariant()
468  .toString().toUInt();
469  pi->m_episode = program.value("Episode").toVariant()
470  .toString().toUInt();
471  pi->m_totalepisodes = program.value("TotalEpisodes").toVariant()
472  .toString().toUInt();
473 
474  pi->m_channel = channel.value("ChannelName").toString("");
475 
476  pi->m_startts = recording.value("StartTs").toString("");
477  pi->m_endts = recording.value("EndTs").toString("");
478  QDateTime recstartts = QDateTime::fromString(pi->m_startts, Qt::ISODate);
479  QDateTime recendts = QDateTime::fromString(pi->m_endts, Qt::ISODate);
480 
481  pi->m_title_pronounce = "";
482  pi->m_credits = V2jsonCastToCredits(cast);
483  pi->m_showtype = "";
484  pi->m_colorcode = "";
485  pi->m_clumpidx = "";
486  pi->m_clumpmax = "";
487 
488  // pi->m_ratings =
489 
490  /* Create a recordedprogram DB entry. */
491  MSqlQuery query(MSqlQuery::InitCon());
492  if (!pi->InsertDB(query, chanid, true))
493  {
494  throw QString("AddRecordedProgram: "
495  "Failed to add recordedprogram entry.");
496  }
497 
498  /* Create recorded DB entry */
499  RecordingInfo ri(pi->m_title, pi->m_title,
500  pi->m_subtitle, pi->m_subtitle,
501  pi->m_description,
502  pi->m_season, pi->m_episode,
503  pi->m_totalepisodes,
504  pi->m_syndicatedepisodenumber,
505  pi->m_category,
506  chanid,
507  channel.value("ChanNum").toString("0"),
508  channel.value("CallSign").toString(""),
509  pi->m_channel,
510  recording.value("RecGroup").toString(""),
511  recording.value("PlayGroup").toString(""),
512  hostname,
513  recording.value("StorageGroup").toString(""),
514  pi->m_airdate,
515  pi->m_partnumber,
516  pi->m_parttotal,
517  pi->m_seriesId,
518  pi->m_programId,
519  pi->m_inetref,
520  pi->m_categoryType,
521  recording.value("Priority").toString("0").toInt(),
522  pi->m_starttime,
523  pi->m_endtime,
524  recstartts,
525  recendts,
526  pi->m_stars,
527  pi->m_originalairdate,
528  program.value("Repeat").toString("false").toLower() == "true",
529  static_cast<RecStatus::Type>(recording.value("Status").toInt()),
530  false, // reactivate
531  recording.value("RecordedId").toString("0").toInt(),
532  0, // parentid
533  static_cast<RecordingType>(recording.value("RecType").toInt()),
534  static_cast<RecordingDupInType>(recording.value("DupInType").toInt()),
535  static_cast<RecordingDupMethodType>(recording.value("DupMethod").toInt()),
536  channel.value("SourceId").toVariant().toString().toUInt(),
537  channel.value("InputId").toVariant().toString().toUInt(),
538  0, // findid
539  channel.value("CommFree").toBool(),
540  pi->m_subtitleType,
541  pi->m_videoProps,
542  pi->m_audioProps,
543  false, // future
544  0, // schedorder
545  0, // mplexid
546  0, // sgroupid,
547  recording.value("EncoderName").toString(""));
548 
549  ri.ProgramFlagsFromNames(program.value("ProgramFlagNames").toString(""));
550 
551  QString filename = program.value("FileName").toString("");
552  QString ext("");
553  int idx = filename.lastIndexOf('.');
554  if (idx > 0)
555  ext = filename.right(filename.size() - idx - 1);
556  // Inserts this RecordingInfo into the database as an existing recording
557  if (!ri.InsertRecording(ext, true))
558  throw QString("Failed to create RecordingInfo database entry. "
559  "Non unique starttime?");
560 
561  ri.InsertFile();
562 
565  ri.SavePreserve(ri.IsPreserved());
568  ri.SaveWatched(ri.IsWatched());
569  // TODO: Cutlist
570 
572  ri.SendUpdateEvent();
573 
574  return ri.GetRecordingID();
575 }
576 
578 //
580 
581 bool V2Dvr::RemoveRecorded(int RecordedId,
582  int chanid, const QDateTime &StartTime,
583  bool forceDelete, bool allowRerecord)
584 {
585  return DeleteRecording(RecordedId, chanid, StartTime, forceDelete,
586  allowRerecord);
587 }
588 
589 
590 bool V2Dvr::DeleteRecording(int RecordedId,
591  int chanid, const QDateTime &StartTime,
592  bool forceDelete, bool allowRerecord)
593 {
594  if ((RecordedId <= 0) &&
595  (chanid <= 0 || !StartTime.isValid()))
596  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
597 
598  // TODO Should use RecordingInfo
599  ProgramInfo pi;
600  if (RecordedId > 0)
601  pi = ProgramInfo(RecordedId);
602  else
603  pi = ProgramInfo(chanid, StartTime.toUTC());
604 
605  if (pi.GetChanID() && pi.HasPathname())
606  {
607  QString cmd = QString("DELETE_RECORDING %1 %2 %3 %4")
608  .arg(QString::number(pi.GetChanID()),
610  forceDelete ? "FORCE" : "NO_FORCE",
611  allowRerecord ? "FORGET" : "NO_FORGET");
612  MythEvent me(cmd);
613 
614  gCoreContext->dispatch(me);
615  return true;
616  }
617 
618  return false;
619 }
620 
622 //
624 
625 bool V2Dvr::UnDeleteRecording(int RecordedId,
626  int chanid, const QDateTime &StartTime)
627 {
628  if ((RecordedId <= 0) &&
629  (chanid <= 0 || !StartTime.isValid()))
630  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
631 
632  RecordingInfo ri;
633  if (RecordedId > 0)
634  ri = RecordingInfo(RecordedId);
635  else
636  ri = RecordingInfo(chanid, StartTime.toUTC());
637 
638  if (ri.GetChanID() && ri.HasPathname())
639  {
640  QString cmd = QString("UNDELETE_RECORDING %1 %2")
641  .arg(ri.GetChanID())
643  MythEvent me(cmd);
644 
645  gCoreContext->dispatch(me);
646  return true;
647  }
648 
649  return false;
650 }
651 
653 //
655 
656 bool V2Dvr::StopRecording(int RecordedId)
657 {
658  if (RecordedId <= 0)
659  throw QString("RecordedId param is invalid.");
660 
661  RecordingInfo ri = RecordingInfo(RecordedId);
662 
663  if (ri.GetChanID())
664  {
665  QString cmd = QString("STOP_RECORDING %1 %2")
666  .arg(ri.GetChanID())
668  MythEvent me(cmd);
669 
670  gCoreContext->dispatch(me);
671  return true;
672  }
673  throw QString("RecordedId %1 not found").arg(RecordedId);
674 
675  return false;
676 }
677 
679 //
681 
682 bool V2Dvr::ReactivateRecording(int RecordedId,
683  int chanid, const QDateTime &StartTime)
684 {
685  if ((RecordedId <= 0) &&
686  (chanid <= 0 || !StartTime.isValid()))
687  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
688 
689  RecordingInfo ri;
690  if (RecordedId > 0)
691  ri = RecordingInfo(RecordedId);
692  else
693  ri = RecordingInfo(chanid, StartTime.toUTC());
694 
695  if (ri.GetChanID() && ri.HasPathname())
696  {
697  ri.ReactivateRecording();
698  return true;
699  }
700 
701  return false;
702 }
703 
705 //
707 
709 {
710  ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(),
711  "RescheduleRecordings");
712  return true;
713 }
714 
716 //
718 
719 bool V2Dvr::AllowReRecord ( int RecordedId )
720 {
721  if (RecordedId <= 0)
722  throw QString("RecordedId param is invalid.");
723 
724  RecordingInfo ri = RecordingInfo(RecordedId);
725 
726  if (!ri.GetChanID())
727  throw QString("RecordedId %1 not found").arg(RecordedId);
728 
729  ri.ForgetHistory();
730 
731  return true;
732 }
733 
735 //
737 
739  int chanid,
740  const QDateTime &StartTime,
741  bool watched)
742 {
743  LOG(VB_GENERAL, LOG_WARNING, "Deprecated, use Dvr/UpdateRecordedMetadata.");
744 
745  if ((RecordedId <= 0) &&
746  (chanid <= 0 || !StartTime.isValid()))
747  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
748 
749  // TODO Should use RecordingInfo
750  ProgramInfo pi;
751  if (RecordedId > 0)
752  pi = ProgramInfo(RecordedId);
753  else
754  pi = ProgramInfo(chanid, StartTime.toUTC());
755 
756  if (pi.GetChanID() && pi.HasPathname())
757  {
758  pi.SaveWatched(watched);
759  return true;
760  }
761 
762  return false;
763 }
764 
766 //
768 
769 long V2Dvr::GetSavedBookmark( int RecordedId,
770  int chanid,
771  const QDateTime &StartTime,
772  const QString &offsettype )
773 {
774  if ((RecordedId <= 0) &&
775  (chanid <= 0 || !StartTime.isValid()))
776  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
777 
778  RecordingInfo ri;
779  if (RecordedId > 0)
780  ri = RecordingInfo(RecordedId);
781  else
782  ri = RecordingInfo(chanid, StartTime.toUTC());
783  uint64_t offset = 0;
784  bool isend=true;
785  uint64_t position = ri.QueryBookmark();
786  // if no bookmark return 0
787  if (position == 0)
788  return 0;
789  if (offsettype.toLower() == "position"){
790  // if bookmark cannot be converted to a keyframe we will
791  // just return the actual frame saved as the bookmark
792  if (ri.QueryKeyFramePosition(&offset, position, isend))
793  return offset;
794  }
795  if (offsettype.toLower() == "duration"){
796  if (ri.QueryKeyFrameDuration(&offset, position, isend))
797  return offset;
798  // If bookmark cannot be converted to a duration return -1
799  return -1;
800  }
801  return position;
802 }
803 
805 // Get last play position
806 // Providing -1 for the RecordedId will return response of -1.
807 // This is a way to check if this api, and the other LastPlayPos APIs,
808 // are supported
810 
811 long V2Dvr::GetLastPlayPos( int RecordedId,
812  int chanid,
813  const QDateTime &StartTime,
814  const QString &offsettype )
815 {
816  if (RecordedId == -1)
817  return -1;
818 
819  if ((RecordedId <= 0) &&
820  (chanid <= 0 || !StartTime.isValid()))
821  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
822 
823  RecordingInfo ri;
824  if (RecordedId > 0)
825  ri = RecordingInfo(RecordedId);
826  else
827  ri = RecordingInfo(chanid, StartTime.toUTC());
828  uint64_t offset = 0;
829  bool isend=true;
830  uint64_t position = ri.QueryLastPlayPos();
831  // if no bookmark return 0
832  if (position == 0)
833  return 0;
834  if (offsettype.toLower() == "position"){
835  // if bookmark cannot be converted to a keyframe we will
836  // just return the actual frame saved as the bookmark
837  if (ri.QueryKeyFramePosition(&offset, position, isend))
838  return offset;
839  }
840  if (offsettype.toLower() == "duration"){
841  if (ri.QueryKeyFrameDuration(&offset, position, isend))
842  return offset;
843  // If bookmark cannot be converted to a duration return -1
844  return -1;
845  }
846  return position;
847 }
848 
850 //
852 
853 bool V2Dvr::SetSavedBookmark( int RecordedId,
854  int chanid,
855  const QDateTime &StartTime,
856  const QString &offsettype,
857  long Offset )
858 {
859  LOG(VB_GENERAL, LOG_WARNING, "Deprecated, use Dvr/UpdateRecordedMetadata.");
860 
861  if ((RecordedId <= 0) &&
862  (chanid <= 0 || !StartTime.isValid()))
863  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
864 
865  if (Offset < 0)
866  throw QString("Offset must be >= 0.");
867 
868  RecordingInfo ri;
869  if (RecordedId > 0)
870  ri = RecordingInfo(RecordedId);
871  else
872  ri = RecordingInfo(chanid, StartTime.toUTC());
873  uint64_t position = 0;
874  bool isend=true;
875  if (offsettype.toLower() == "position"){
876  if (!ri.QueryPositionKeyFrame(&position, Offset, isend))
877  return false;
878  }
879  else if (offsettype.toLower() == "duration"){
880  if (!ri.QueryDurationKeyFrame(&position, Offset, isend))
881  return false;
882  }
883  else
884  position = Offset;
885  ri.SaveBookmark(position);
886  return true;
887 }
888 
890 // Set last Play Position. Check if this is supported by first calling
891 // Get Last Play Position with -1.
893 
894 bool V2Dvr::SetLastPlayPos( int RecordedId,
895  int chanid,
896  const QDateTime &StartTime,
897  const QString &offsettype,
898  long Offset )
899 {
900  if ((RecordedId <= 0) &&
901  (chanid <= 0 || !StartTime.isValid()))
902  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
903 
904  if (Offset < 0)
905  throw QString("Offset must be >= 0.");
906 
907  RecordingInfo ri;
908  if (RecordedId > 0)
909  ri = RecordingInfo(RecordedId);
910  else
911  ri = RecordingInfo(chanid, StartTime.toUTC());
912  uint64_t position = 0;
913  bool isend=true;
914  if (offsettype.toLower() == "position"){
915  if (!ri.QueryPositionKeyFrame(&position, Offset, isend))
916  return false;
917  }
918  else if (offsettype.toLower() == "duration"){
919  if (!ri.QueryDurationKeyFrame(&position, Offset, isend))
920  return false;
921  }
922  else
923  position = Offset;
924  ri.SaveLastPlayPos(position);
925  return true;
926 }
927 
929  int chanid,
930  const QDateTime &StartTime,
931  const QString &offsettype )
932 {
933  int marktype = 0;
934  if ((RecordedId <= 0) &&
935  (chanid <= 0 || !StartTime.isValid()))
936  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
937 
938  RecordingInfo ri;
939  if (RecordedId > 0)
940  ri = RecordingInfo(RecordedId);
941  else
942  ri = RecordingInfo(chanid, StartTime.toUTC());
943 
944  auto* pCutList = new V2CutList();
945  if (offsettype.toLower() == "position")
946  marktype = 1;
947  else if (offsettype.toLower() == "duration")
948  marktype = 2;
949  else
950  marktype = 0;
951 
952  V2FillCutList(pCutList, &ri, marktype);
953 
954  return pCutList;
955 }
956 
958 //
960 
962  int chanid,
963  const QDateTime &StartTime,
964  const QString &offsettype )
965 {
966  int marktype = 0;
967  if ((RecordedId <= 0) &&
968  (chanid <= 0 || !StartTime.isValid()))
969  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
970 
971  RecordingInfo ri;
972  if (RecordedId > 0)
973  ri = RecordingInfo(RecordedId);
974  else
975  ri = RecordingInfo(chanid, StartTime.toUTC());
976 
977  auto* pCutList = new V2CutList();
978  if (offsettype.toLower() == "position")
979  marktype = 1;
980  else if (offsettype.toLower() == "duration")
981  marktype = 2;
982  else
983  marktype = 0;
984 
985  V2FillCommBreak(pCutList, &ri, marktype);
986 
987  return pCutList;
988 }
989 
991 //
993 
995  const QString &offsettype )
996 {
997  MarkTypes marktype = MARK_UNSET;
998  if (RecordedId <= 0)
999  throw QString("Recorded ID appears invalid.");
1000 
1001  RecordingInfo ri;
1002  ri = RecordingInfo(RecordedId);
1003 
1004  auto* pCutList = new V2CutList();
1005  if (offsettype.toLower() == "bytes")
1006  marktype = MARK_GOP_BYFRAME;
1007  else if (offsettype.toLower() == "duration")
1008  marktype = MARK_DURATION_MS;
1009  else
1010  {
1011  delete pCutList;
1012  throw QString("Type must be 'BYTES' or 'DURATION'.");
1013  }
1014 
1015  V2FillSeek(pCutList, &ri, marktype);
1016 
1017  return pCutList;
1018 }
1019 
1021 //
1023 
1025 {
1026  RecordingInfo ri;
1027  ri = RecordingInfo(RecordedId);
1028 
1029  if (!ri.HasPathname())
1030  throw QString("Invalid RecordedId %1").arg(RecordedId);
1031 
1032  QVector<ProgramInfo::MarkupEntry> mapMark;
1033  QVector<ProgramInfo::MarkupEntry> mapSeek;
1034 
1035  ri.QueryMarkup(mapMark, mapSeek);
1036 
1037  auto* pMarkupList = new V2MarkupList();
1038  for (const auto& entry : qAsConst(mapMark))
1039  {
1040  V2Markup *pMarkup = pMarkupList->AddNewMarkup();
1041  QString typestr = toString(static_cast<MarkTypes>(entry.type));
1042  pMarkup->setType(typestr);
1043  pMarkup->setFrame(entry.frame);
1044  if (entry.isDataNull)
1045  pMarkup->setData("NULL");
1046  else
1047  pMarkup->setData(QString::number(entry.data));
1048  }
1049  for (auto entry : qAsConst(mapSeek))
1050  {
1051  V2Markup *pSeek = pMarkupList->AddNewSeek();
1052  QString typestr = toString(static_cast<MarkTypes>(entry.type));
1053  pSeek->setType(typestr);
1054  pSeek->setFrame(entry.frame);
1055  if (entry.isDataNull)
1056  pSeek->setData("NULL");
1057  else
1058  pSeek->setData(QString::number(entry.data));
1059  }
1060 
1061 
1062  return pMarkupList;
1063 }
1064 
1066 //
1068 
1069 bool V2Dvr::SetRecordedMarkup(int RecordedId, const QString &MarkupList)
1070 {
1071  RecordingInfo ri;
1072  ri = RecordingInfo(RecordedId);
1073 
1074  if (!ri.HasPathname())
1075  throw QString("Invalid RecordedId %1").arg(RecordedId);
1076 
1077  QVector<ProgramInfo::MarkupEntry> mapMark;
1078  QVector<ProgramInfo::MarkupEntry> mapSeek;
1079 
1080  QJsonDocument doc = QJsonDocument::fromJson(MarkupList.toUtf8());
1081  QJsonObject markuplist = doc.object();
1082 
1083  QJsonArray marks = markuplist["Mark"].toArray();
1084  for (const auto & m : marks)
1085  {
1086  QJsonObject markup = m.toObject();
1088 
1089  QString typestr = markup.value("Type").toString("");
1090  entry.type = markTypeFromString(typestr);
1091  entry.frame = markup.value("Frame").toVariant()
1092  .toString().toLongLong();
1093  QString data = markup.value("Data").toString("NULL");
1094  entry.isDataNull = (data == "NULL");
1095  if (!entry.isDataNull)
1096  entry.data = data.toLongLong();
1097 
1098  mapMark.append(entry);
1099  }
1100 
1101  QJsonArray seeks = markuplist["Seek"].toArray();
1102  for (const auto & m : seeks)
1103  {
1104  QJsonObject markup = m.toObject();
1106 
1107  QString typestr = markup.value("Type").toString("");
1108  entry.type = markTypeFromString(typestr);
1109  entry.frame = markup.value("Frame").toVariant().toString().toLongLong();
1110  QString data = markup.value("Data").toString("NULL");
1111  entry.isDataNull = (data == "NULL");
1112  if (!entry.isDataNull)
1113  entry.data = data.toLongLong();
1114 
1115  mapSeek.append(entry);
1116  }
1117 
1118  ri.SaveMarkup(mapMark, mapSeek);
1119 
1120  return true;
1121 }
1122 
1124 //
1126 
1128 {
1129  auto* pList = new V2EncoderList();
1130  FillEncoderList(pList->GetEncoders(), pList);
1131  return pList;
1132 }
1133 
1135 //
1137 
1139 {
1140  auto *pList = new V2InputList();
1141 
1142  QList<InputInfo> inputInfoList = CardUtil::GetAllInputInfo();
1143  for (const auto & inputInfo : qAsConst(inputInfoList))
1144  {
1145  V2Input *input = pList->AddNewInput();
1146  V2FillInputInfo(input, inputInfo);
1147  }
1148 
1149  return pList;
1150 }
1151 
1153 //
1155 
1157 {
1158  MSqlQuery query(MSqlQuery::InitCon());
1159  query.prepare("SELECT recgroup FROM recgroups WHERE recgroup <> 'Deleted' "
1160  "ORDER BY recgroup");
1161 
1162  QStringList result;
1163  if (!query.exec())
1164  {
1165  MythDB::DBError("GetRecGroupList", query);
1166  return result;
1167  }
1168 
1169  while (query.next())
1170  result << query.value(0).toString();
1171 
1172  return result;
1173 }
1174 
1176 //
1178 
1179 QStringList V2Dvr::GetProgramCategories( bool OnlyRecorded )
1180 {
1181  MSqlQuery query(MSqlQuery::InitCon());
1182 
1183  if (OnlyRecorded)
1184  query.prepare("SELECT DISTINCT category FROM recorded ORDER BY category");
1185  else
1186  query.prepare("SELECT DISTINCT category FROM program ORDER BY category");
1187 
1188  QStringList result;
1189  if (!query.exec())
1190  {
1191  MythDB::DBError("GetProgramCategories", query);
1192  return result;
1193  }
1194 
1195  while (query.next())
1196  result << query.value(0).toString();
1197 
1198  return result;
1199 }
1200 
1202 //
1204 
1206 {
1208 }
1209 
1211 //
1213 
1215 {
1216  return PlayGroup::GetNames();
1217 }
1218 
1220 //
1222 
1224 {
1225  auto* filterList = new V2RecRuleFilterList();
1226 
1227  MSqlQuery query(MSqlQuery::InitCon());
1228 
1229  query.prepare("SELECT filterid, description, newruledefault "
1230  "FROM recordfilter ORDER BY filterid");
1231 
1232  if (query.exec())
1233  {
1234  while (query.next())
1235  {
1236  V2RecRuleFilter* ruleFilter = filterList->AddNewRecRuleFilter();
1237  ruleFilter->setId(query.value(0).toInt());
1238  ruleFilter->setDescription(QObject::tr(query.value(1).toString()
1239  .toUtf8().constData()));
1240  }
1241  }
1242 
1243  return filterList;
1244 }
1245 
1247 //
1249 
1250 QStringList V2Dvr::GetTitleList(const QString& RecGroup)
1251 {
1252  MSqlQuery query(MSqlQuery::InitCon());
1253 
1254  QString querystr = "SELECT DISTINCT title FROM recorded "
1255  "WHERE deletepending = 0";
1256 
1257  if (!RecGroup.isEmpty())
1258  querystr += " AND recgroup = :RECGROUP";
1259  else
1260  querystr += " AND recgroup != 'Deleted'";
1261 
1262  querystr += " ORDER BY title";
1263 
1264  query.prepare(querystr);
1265 
1266  if (!RecGroup.isEmpty())
1267  query.bindValue(":RECGROUP", RecGroup);
1268 
1269  QStringList result;
1270  if (!query.exec())
1271  {
1272  MythDB::DBError("GetTitleList recorded", query);
1273  return result;
1274  }
1275 
1276  while (query.next())
1277  result << query.value(0).toString();
1278 
1279  return result;
1280 }
1281 
1283 //
1285 
1287 {
1288  MSqlQuery query(MSqlQuery::InitCon());
1289 
1290  QString querystr = QString(
1291  "SELECT title, inetref, count(title) as count "
1292  " FROM recorded AS r "
1293  " JOIN recgroups AS g ON r.recgroupid = g.recgroupid "
1294  " WHERE g.recgroup NOT IN ('Deleted', 'LiveTV') "
1295  " AND r.deletepending = 0 "
1296  " GROUP BY title, inetref "
1297  " ORDER BY title");
1298 
1299  query.prepare(querystr);
1300 
1301  auto *pTitleInfos = new V2TitleInfoList();
1302  if (!query.exec())
1303  {
1304  MythDB::DBError("GetTitleList recorded", query);
1305  return pTitleInfos;
1306  }
1307 
1308  while (query.next())
1309  {
1310  V2TitleInfo *pTitleInfo = pTitleInfos->AddNewTitleInfo();
1311 
1312  pTitleInfo->setTitle(query.value(0).toString());
1313  pTitleInfo->setInetref(query.value(1).toString());
1314  pTitleInfo->setCount(query.value(2).toInt());
1315  }
1316 
1317  return pTitleInfos;
1318 }
1319 
1320 
1322  int nCount,
1323  int nRecordId )
1324 {
1325  auto *pPrograms = new V2ProgramList();
1326  int size = FillUpcomingList(pPrograms->GetPrograms(), pPrograms,
1327  nStartIndex,
1328  nCount,
1329  true, // bShowAll,
1330  nRecordId,
1331  RecStatus::Conflict); // nRecStatus );
1332 
1333  pPrograms->setStartIndex ( nStartIndex );
1334  pPrograms->setCount ( nCount );
1335  pPrograms->setTotalAvailable( size );
1336  pPrograms->setAsOf ( MythDate::current() );
1337  pPrograms->setVersion ( MYTH_BINARY_VERSION );
1338  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1339 
1340  return pPrograms;
1341 }
1342 
1344  int nCount,
1345  bool bShowAll,
1346  int nRecordId,
1347  int nRecStatus )
1348 {
1349  auto *pPrograms = new V2ProgramList();
1350  int size = FillUpcomingList(pPrograms->GetPrograms(), pPrograms,
1351  nStartIndex,
1352  nCount,
1353  bShowAll,
1354  nRecordId,
1355  nRecStatus );
1356 
1357  pPrograms->setStartIndex ( nStartIndex );
1358  pPrograms->setCount ( nCount );
1359  pPrograms->setTotalAvailable( size );
1360  pPrograms->setAsOf ( MythDate::current() );
1361  pPrograms->setVersion ( MYTH_BINARY_VERSION );
1362  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1363 
1364  return pPrograms;
1365 }
1366 
1368  const QString& sTitle,
1369  const QString& sSubtitle,
1370  const QString& sDescription,
1371  const QString& sCategory,
1372  const QDateTime& StartTime,
1373  const QDateTime& EndTime,
1374  const QString& sSeriesId,
1375  const QString& sProgramId,
1376  int nChanId,
1377  const QString& sStation,
1378  int nFindDay,
1379  QTime tFindTime,
1380  int nParentId,
1381  bool bInactive,
1382  uint nSeason,
1383  uint nEpisode,
1384  const QString& sInetref,
1385  QString sType,
1386  QString sSearchType,
1387  int nRecPriority,
1388  uint nPreferredInput,
1389  int nStartOffset,
1390  int nEndOffset,
1391  const QDateTime& LastRecorded,
1392  QString sDupMethod,
1393  QString sDupIn,
1394  bool bNewEpisOnly,
1395  uint nFilter,
1396  QString sRecProfile,
1397  QString sRecGroup,
1398  QString sStorageGroup,
1399  QString sPlayGroup,
1400  bool bAutoExpire,
1401  int nMaxEpisodes,
1402  bool bMaxNewest,
1403  bool bAutoCommflag,
1404  bool bAutoTranscode,
1405  bool bAutoMetaLookup,
1406  bool bAutoUserJob1,
1407  bool bAutoUserJob2,
1408  bool bAutoUserJob3,
1409  bool bAutoUserJob4,
1410  int nTranscoder)
1411 {
1412  QDateTime recstartts = StartTime.toUTC();
1413  QDateTime recendts = EndTime.toUTC();
1414  QDateTime lastrects = LastRecorded.toUTC();
1415  RecordingRule rule;
1416  rule.LoadTemplate("Default");
1417 
1418  if (sType.isEmpty())
1419  sType = "single";
1420 
1421  if (sSearchType.isEmpty())
1422  sSearchType = "none";
1423 
1424  if (sDupMethod.isEmpty())
1425  sDupMethod = "subtitleanddescription";
1426 
1427  if (sDupIn.isEmpty())
1428  sDupIn = "all";
1429 
1430  rule.m_title = sTitle;
1431  rule.m_subtitle = sSubtitle;
1432  rule.m_description = sDescription;
1433 
1434  rule.m_startdate = recstartts.date();
1435  rule.m_starttime = recstartts.time();
1436  rule.m_enddate = recendts.date();
1437  rule.m_endtime = recendts.time();
1438 
1439  rule.m_type = recTypeFromString(sType);
1440  rule.m_searchType = searchTypeFromString(sSearchType);
1441  if (rule.m_searchType == kManualSearch)
1442  rule.m_dupMethod = kDupCheckNone;
1443  else
1444  rule.m_dupMethod = dupMethodFromString(sDupMethod);
1445  rule.m_dupIn = dupInFromStringAndBool(sDupIn, bNewEpisOnly);
1446 
1447  if (sRecProfile.isEmpty())
1448  sRecProfile = "Default";
1449 
1450  if (sRecGroup.isEmpty())
1451  sRecGroup = "Default";
1452 
1453  if (sStorageGroup.isEmpty())
1454  sStorageGroup = "Default";
1455 
1456  if (sPlayGroup.isEmpty())
1457  sPlayGroup = "Default";
1458 
1459  rule.m_category = sCategory;
1460  rule.m_seriesid = sSeriesId;
1461  rule.m_programid = sProgramId;
1462 
1463  rule.m_channelid = nChanId;
1464  rule.m_station = sStation;
1465 
1466  rule.m_findday = nFindDay;
1467  rule.m_findtime = tFindTime;
1468 
1469  rule.m_recProfile = sRecProfile;
1470  rule.m_recGroupID = RecordingInfo::GetRecgroupID(sRecGroup);
1471  if (rule.m_recGroupID == 0)
1472  {
1473  rule.m_recGroupID = V2CreateRecordingGroup(sRecGroup);
1474  if (rule.m_recGroupID <= 0)
1476  }
1477  rule.m_storageGroup = sStorageGroup;
1478  rule.m_playGroup = sPlayGroup;
1479 
1480  rule.m_parentRecID = nParentId;
1481  rule.m_isInactive = bInactive;
1482 
1483  rule.m_season = nSeason;
1484  rule.m_episode = nEpisode;
1485  rule.m_inetref = sInetref;
1486 
1487  rule.m_recPriority = nRecPriority;
1488  rule.m_prefInput = nPreferredInput;
1489  rule.m_startOffset = nStartOffset;
1490  rule.m_endOffset = nEndOffset;
1491  rule.m_filter = nFilter;
1492 
1493  rule.m_autoExpire = bAutoExpire;
1494  rule.m_maxEpisodes = nMaxEpisodes;
1495  rule.m_maxNewest = bMaxNewest;
1496 
1497  rule.m_autoCommFlag = bAutoCommflag;
1498  rule.m_autoTranscode = bAutoTranscode;
1499  rule.m_autoMetadataLookup = bAutoMetaLookup;
1500 
1501  rule.m_autoUserJob1 = bAutoUserJob1;
1502  rule.m_autoUserJob2 = bAutoUserJob2;
1503  rule.m_autoUserJob3 = bAutoUserJob3;
1504  rule.m_autoUserJob4 = bAutoUserJob4;
1505 
1506  rule.m_transcoder = nTranscoder;
1507 
1508  rule.m_lastRecorded = lastrects;
1509 
1510  QString msg;
1511  if (!rule.IsValid(msg))
1512  throw QString(msg);
1513 
1514  rule.Save();
1515 
1516  uint recid = rule.m_recordID;
1517 
1518  return recid;
1519 }
1520 
1522  const QString& sTitle,
1523  const QString& sSubtitle,
1524  const QString& sDescription,
1525  const QString& sCategory,
1526  const QDateTime& StartTime,
1527  const QDateTime& EndTime,
1528  const QString& sSeriesId,
1529  const QString& sProgramId,
1530  int nChanId,
1531  const QString& sStation,
1532  int nFindDay,
1533  QTime tFindTime,
1534  bool bInactive,
1535  uint nSeason,
1536  uint nEpisode,
1537  const QString& sInetref,
1538  QString sType,
1539  QString sSearchType,
1540  int nRecPriority,
1541  uint nPreferredInput,
1542  int nStartOffset,
1543  int nEndOffset,
1544  QString sDupMethod,
1545  QString sDupIn,
1546  bool bNewEpisOnly,
1547  uint nFilter,
1548  QString sRecProfile,
1549  QString sRecGroup,
1550  QString sStorageGroup,
1551  QString sPlayGroup,
1552  bool bAutoExpire,
1553  int nMaxEpisodes,
1554  bool bMaxNewest,
1555  bool bAutoCommflag,
1556  bool bAutoTranscode,
1557  bool bAutoMetaLookup,
1558  bool bAutoUserJob1,
1559  bool bAutoUserJob2,
1560  bool bAutoUserJob3,
1561  bool bAutoUserJob4,
1562  int nTranscoder)
1563 {
1564  if (nRecordId == 0 )
1565  throw QString("Record ID is invalid.");
1566 
1567  RecordingRule pRule;
1568  pRule.m_recordID = nRecordId;
1569  pRule.Load();
1570 
1571  if (!pRule.IsLoaded())
1572  throw QString("Record ID does not exist.");
1573 
1574  QDateTime recstartts = StartTime.toUTC();
1575  QDateTime recendts = EndTime.toUTC();
1576 
1577  pRule.m_isInactive = bInactive;
1578  if (sType.isEmpty())
1579  sType = "single";
1580 
1581  if (sSearchType.isEmpty())
1582  sSearchType = "none";
1583 
1584  if (sDupMethod.isEmpty())
1585  sDupMethod = "subtitleanddescription";
1586 
1587  if (sDupIn.isEmpty())
1588  sDupIn = "all";
1589 
1590  pRule.m_type = recTypeFromString(sType);
1591  pRule.m_searchType = searchTypeFromString(sSearchType);
1592  if (pRule.m_searchType == kManualSearch)
1593  pRule.m_dupMethod = kDupCheckNone;
1594  else
1595  pRule.m_dupMethod = dupMethodFromString(sDupMethod);
1596  pRule.m_dupIn = dupInFromStringAndBool(sDupIn, bNewEpisOnly);
1597 
1598  if (sRecProfile.isEmpty())
1599  sRecProfile = "Default";
1600 
1601  if (sRecGroup.isEmpty())
1602  sRecGroup = "Default";
1603 
1604  if (sStorageGroup.isEmpty())
1605  sStorageGroup = "Default";
1606 
1607  if (sPlayGroup.isEmpty())
1608  sPlayGroup = "Default";
1609 
1610  if (!sTitle.isEmpty())
1611  pRule.m_title = sTitle;
1612 
1613  if (!sSubtitle.isEmpty())
1614  pRule.m_subtitle = sSubtitle;
1615 
1616  if(!sDescription.isEmpty())
1617  pRule.m_description = sDescription;
1618 
1619  if (!sCategory.isEmpty())
1620  pRule.m_category = sCategory;
1621 
1622  if (!sSeriesId.isEmpty())
1623  pRule.m_seriesid = sSeriesId;
1624 
1625  if (!sProgramId.isEmpty())
1626  pRule.m_programid = sProgramId;
1627 
1628  if (nChanId)
1629  pRule.m_channelid = nChanId;
1630  if (!sStation.isEmpty())
1631  pRule.m_station = sStation;
1632 
1633  pRule.m_startdate = recstartts.date();
1634  pRule.m_starttime = recstartts.time();
1635  pRule.m_enddate = recendts.date();
1636  pRule.m_endtime = recendts.time();
1637 
1638  pRule.m_findday = nFindDay;
1639  pRule.m_findtime = tFindTime;
1640 
1641  pRule.m_recProfile = sRecProfile;
1642  pRule.m_recGroupID = RecordingInfo::GetRecgroupID(sRecGroup);
1643  if (pRule.m_recGroupID == 0)
1644  {
1645  pRule.m_recGroupID = V2CreateRecordingGroup(sRecGroup);
1646  if (pRule.m_recGroupID <= 0)
1648  }
1649  pRule.m_storageGroup = sStorageGroup;
1650  pRule.m_playGroup = sPlayGroup;
1651 
1652  pRule.m_isInactive = bInactive;
1653 
1654  pRule.m_season = nSeason;
1655  pRule.m_episode = nEpisode;
1656  pRule.m_inetref = sInetref;
1657 
1658  pRule.m_recPriority = nRecPriority;
1659  pRule.m_prefInput = nPreferredInput;
1660  pRule.m_startOffset = nStartOffset;
1661  pRule.m_endOffset = nEndOffset;
1662  pRule.m_filter = nFilter;
1663 
1664  pRule.m_autoExpire = bAutoExpire;
1665  pRule.m_maxEpisodes = nMaxEpisodes;
1666  pRule.m_maxNewest = bMaxNewest;
1667 
1668  pRule.m_autoCommFlag = bAutoCommflag;
1669  pRule.m_autoTranscode = bAutoTranscode;
1670  pRule.m_autoMetadataLookup = bAutoMetaLookup;
1671 
1672  pRule.m_autoUserJob1 = bAutoUserJob1;
1673  pRule.m_autoUserJob2 = bAutoUserJob2;
1674  pRule.m_autoUserJob3 = bAutoUserJob3;
1675  pRule.m_autoUserJob4 = bAutoUserJob4;
1676 
1677  pRule.m_transcoder = nTranscoder;
1678 
1679  QString msg;
1680  if (!pRule.IsValid(msg))
1681  throw QString(msg);
1682 
1683  bool bResult = pRule.Save();
1684 
1685  return bResult;
1686 }
1687 
1689 {
1690  bool bResult = false;
1691 
1692  if (nRecordId == 0 )
1693  throw QString("Record ID does not exist.");
1694 
1695  RecordingRule pRule;
1696  pRule.m_recordID = nRecordId;
1697 
1698  bResult = pRule.Delete();
1699 
1700  return bResult;
1701 }
1702 
1703 bool V2Dvr::AddDontRecordSchedule(int nChanId, const QDateTime &dStartTime,
1704  bool bNeverRecord)
1705 {
1706  bool bResult = true;
1707 
1708  if (nChanId <= 0 || !dStartTime.isValid())
1709  throw QString("Program does not exist.");
1710 
1711  ProgramInfo *pi = LoadProgramFromProgram(nChanId, dStartTime.toUTC());
1712 
1713  if (!pi)
1714  throw QString("Program does not exist.");
1715 
1716  // Why RecordingInfo instead of ProgramInfo? Good question ...
1717  RecordingInfo recInfo = RecordingInfo(*pi);
1718 
1719  delete pi;
1720 
1721  if (bNeverRecord)
1722  {
1723  recInfo.ApplyNeverRecord();
1724  }
1725  else
1727 
1728  return bResult;
1729 }
1730 
1732  int nCount,
1733  const QString &Sort,
1734  bool Descending )
1735 {
1737  if (Sort.toLower() == "lastrecorded")
1738  sortingColumn = Scheduler::kSortLastRecorded;
1739  else if (Sort.toLower() == "nextrecording")
1740  sortingColumn = Scheduler::kSortNextRecording;
1741  else if (Sort.toLower() == "title")
1742  sortingColumn = Scheduler::kSortTitle; // NOLINT(bugprone-branch-clone)
1743  else if (Sort.toLower() == "priority")
1744  sortingColumn = Scheduler::kSortPriority;
1745  else if (Sort.toLower() == "type")
1746  sortingColumn = Scheduler::kSortType;
1747  else
1748  sortingColumn = Scheduler::kSortTitle;
1749 
1750  RecList recList;
1751  Scheduler::GetAllScheduled(recList, sortingColumn, !Descending);
1752 
1753  // ----------------------------------------------------------------------
1754  // Build Response
1755  // ----------------------------------------------------------------------
1756 
1757  auto *pRecRules = new V2RecRuleList();
1758 
1759  nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (int)recList.size() ) : 0;
1760  nCount = (nCount > 0) ? std::min( nCount, (int)recList.size() ) : recList.size();
1761  int nEndIndex = std::min((nStartIndex + nCount), (int)recList.size() );
1762 
1763  for( int n = nStartIndex; n < nEndIndex; n++)
1764  {
1765  RecordingInfo *info = recList[n];
1766 
1767  if (info != nullptr)
1768  {
1769  V2RecRule *pRecRule = pRecRules->AddNewRecRule();
1770 
1771  V2FillRecRuleInfo( pRecRule, info->GetRecordingRule() );
1772  }
1773  }
1774 
1775  // ----------------------------------------------------------------------
1776 
1777  pRecRules->setStartIndex ( nStartIndex );
1778  pRecRules->setCount ( nCount );
1779  pRecRules->setTotalAvailable( recList.size() );
1780  pRecRules->setAsOf ( MythDate::current() );
1781  pRecRules->setVersion ( MYTH_BINARY_VERSION );
1782  pRecRules->setProtoVer ( MYTH_PROTO_VERSION );
1783 
1784  while (!recList.empty())
1785  {
1786  delete recList.back();
1787  recList.pop_back();
1788  }
1789 
1790  return pRecRules;
1791 }
1792 
1794  const QString& sTemplate,
1795  int nRecordedId,
1796  int nChanId,
1797  const QDateTime& StartTime,
1798  bool bMakeOverride )
1799 {
1800  RecordingRule rule;
1801  QDateTime dStartTime = StartTime.toUTC();
1802 
1803  if (nRecordId > 0)
1804  {
1805  rule.m_recordID = nRecordId;
1806  if (!rule.Load())
1807  throw QString("Record ID does not exist.");
1808  }
1809  else if (!sTemplate.isEmpty())
1810  {
1811  if (!rule.LoadTemplate(sTemplate))
1812  throw QString("Template does not exist.");
1813  }
1814  else if (nRecordedId > 0) // Loads from the Recorded/Recorded Program Table
1815  {
1816  // Despite the use of ProgramInfo, this only applies to Recordings.
1817  ProgramInfo recInfo(nRecordedId);
1818  if (!rule.LoadByProgram(&recInfo))
1819  throw QString("Recording does not exist");
1820  }
1821  else if (nChanId > 0 && dStartTime.isValid()) // Loads from Program Table, should NOT be used with recordings
1822  {
1823  // Despite the use of RecordingInfo, this only applies to programs in the
1824  // present or future, not to recordings? Confused yet?
1826  RecordingInfo info(nChanId, dStartTime, false, 0h, &status);
1827  if (status != RecordingInfo::kFoundProgram)
1828  throw QString("Program does not exist.");
1829  RecordingRule *pRule = info.GetRecordingRule();
1830  if (bMakeOverride && rule.m_type != kSingleRecord &&
1831  rule.m_type != kOverrideRecord && rule.m_type != kDontRecord)
1832  pRule->MakeOverride();
1833  rule = *pRule;
1834  }
1835  else
1836  {
1837  throw QString("Invalid request.");
1838  }
1839 
1840  auto *pRecRule = new V2RecRule();
1841  V2FillRecRuleInfo( pRecRule, &rule );
1842 
1843  return pRecRule;
1844 }
1845 
1847 {
1848  bool bResult = false;
1849 
1850  if (nRecordId == 0 )
1851  throw QString("Record ID appears invalid.");
1852 
1853  RecordingRule pRule;
1854  pRule.m_recordID = nRecordId;
1855  pRule.Load();
1856 
1857  if (pRule.IsLoaded())
1858  {
1859  pRule.m_isInactive = false;
1860  bResult = pRule.Save();
1861  }
1862 
1863  return bResult;
1864 }
1865 
1867 {
1868  bool bResult = false;
1869 
1870  if (nRecordId == 0 )
1871  throw QString("Record ID appears invalid.");
1872 
1873  RecordingRule pRule;
1874  pRule.m_recordID = nRecordId;
1875  pRule.Load();
1876 
1877  if (pRule.IsLoaded())
1878  {
1879  pRule.m_isInactive = true;
1880  bResult = pRule.Save();
1881  }
1882 
1883  return bResult;
1884 }
1885 
1886 int V2Dvr::RecordedIdForKey(int chanid, const QDateTime &StartTime)
1887 {
1888  int recordedid = 0;
1889 
1890  if (!RecordingInfo::QueryRecordedIdForKey(recordedid, chanid,
1891  StartTime))
1892  return -1;
1893 
1894  return recordedid;
1895 }
1896 
1897 int V2Dvr::RecordedIdForPathname(const QString & pathname)
1898 {
1899  uint recordedid = 0;
1900 
1901  if (!ProgramInfo::QueryRecordedIdFromPathname(pathname, recordedid))
1902  return -1;
1903 
1904  return recordedid;
1905 }
1906 
1908 {
1909  auto type = static_cast<RecStatus::Type>(RecStatus);
1910  return RecStatus::toString(type);
1911 }
1912 
1913 QString V2Dvr::RecStatusToDescription(int RecStatus, int recType,
1914  const QDateTime &StartTime)
1915 {
1916  //if (!StartTime.isValid())
1917  // throw QString("StartTime appears invalid.");
1918  auto recstatusType = static_cast<RecStatus::Type>(RecStatus);
1919  auto recordingType = static_cast<RecordingType>(recType);
1920  return RecStatus::toDescription(recstatusType, recordingType, StartTime);
1921 }
1922 
1923 QString V2Dvr::RecTypeToString(const QString& recType)
1924 {
1925  bool ok = false;
1926  auto enumType = static_cast<RecordingType>(recType.toInt(&ok, 10));
1927  if (ok)
1928  return toString(enumType);
1929  // RecordingType type = static_cast<RecordingType>(recType);
1930  return toString(recTypeFromString(recType));
1931 }
1932 
1933 QString V2Dvr::RecTypeToDescription(const QString& recType)
1934 {
1935  bool ok = false;
1936  auto enumType = static_cast<RecordingType>(recType.toInt(&ok, 10));
1937  if (ok)
1938  return toDescription(enumType);
1939  // RecordingType type = static_cast<RecordingType>(recType);
1940  return toDescription(recTypeFromString(recType));
1941 }
1942 
1943 QString V2Dvr::DupInToString(const QString& DupIn)
1944 {
1945  // RecordingDupInType type= static_cast<RecordingDupInType>(DupIn);
1946  // return toString(type);
1947  return toString(dupInFromString(DupIn));
1948 }
1949 
1950 QString V2Dvr::DupInToDescription(const QString& DupIn)
1951 {
1952  // RecordingDupInType type= static_cast<RecordingDupInType>(DupIn);
1953  //return toDescription(type);
1954  return toDescription(dupInFromString(DupIn));
1955 }
1956 
1957 QString V2Dvr::DupMethodToString(const QString& DupMethod)
1958 {
1959  // RecordingDupMethodType method = static_cast<RecordingDupMethodType>(DupMethod);
1960  return toString(dupMethodFromString(DupMethod));
1961 }
1962 
1963 QString V2Dvr::DupMethodToDescription(const QString& DupMethod)
1964 {
1965  // RecordingDupMethodType method = static_cast<RecordingDupMethodType>(DupMethod);
1966  return toDescription(dupMethodFromString(DupMethod));
1967 }
1968 
1970 //
1972 
1973 int V2Dvr::ManageJobQueue( const QString &sAction,
1974  const QString &sJobName,
1975  int nJobId,
1976  int nRecordedId,
1977  QDateTime JobStartTime,
1978  QString sRemoteHost,
1979  QString sJobArgs )
1980 {
1981  int nReturn = -1;
1982 
1983  if (!HAS_PARAMv2("JobName") ||
1984  !HAS_PARAMv2("RecordedId") )
1985  {
1986  LOG(VB_GENERAL, LOG_ERR, "JobName and RecordedId are required.");
1987  return nReturn;
1988  }
1989 
1990  if (sRemoteHost.isEmpty())
1991  sRemoteHost = gCoreContext->GetHostName();
1992 
1993  int jobType = JobQueue::GetJobTypeFromName(sJobName);
1994 
1995  if (jobType == JOB_NONE)
1996  return nReturn;
1997 
1998  RecordingInfo ri = RecordingInfo(nRecordedId);
1999 
2000  if (!ri.GetChanID())
2001  return nReturn;
2002 
2003  if ( sAction == "Remove")
2004  {
2005  if (!HAS_PARAMv2("JobId") || nJobId < 0)
2006  {
2007  LOG(VB_GENERAL, LOG_ERR, "For Remove, a valid JobId is required.");
2008  return nReturn;
2009  }
2010 
2011  if (!JobQueue::SafeDeleteJob(nJobId, jobType, ri.GetChanID(),
2012  ri.GetRecordingStartTime()))
2013  return nReturn;
2014 
2015  return nJobId;
2016  }
2017 
2018  if ( sAction != "Add")
2019  {
2020  LOG(VB_GENERAL, LOG_ERR, QString("Illegal Action name '%1'. Use: Add, "
2021  "or Remove").arg(sAction));
2022  return nReturn;
2023  }
2024 
2025  if (((jobType & JOB_USERJOB) != 0) &&
2026  gCoreContext->GetSetting(sJobName, "").isEmpty())
2027  {
2028  LOG(VB_GENERAL, LOG_ERR, QString("%1 hasn't been defined.")
2029  .arg(sJobName));
2030  return nReturn;
2031  }
2032 
2033  if (!gCoreContext->GetBoolSettingOnHost(QString("JobAllow%1").arg(sJobName),
2034  sRemoteHost, false))
2035  {
2036  LOG(VB_GENERAL, LOG_ERR, QString("%1 hasn't been allowed on host %2.")
2037  .arg(sJobName, sRemoteHost));
2038  return nReturn;
2039  }
2040 
2041  if (!JobStartTime.isValid())
2042  JobStartTime = QDateTime::currentDateTime();
2043 
2044  if (!JobQueue::InJobRunWindow(JobStartTime))
2045  return nReturn;
2046 
2047  if (sJobArgs.isNull())
2048  sJobArgs = "";
2049 
2050  bool bReturn = JobQueue::QueueJob(jobType,
2051  ri.GetChanID(),
2052  ri.GetRecordingStartTime(),
2053  sJobArgs,
2054  QString("Dvr/ManageJobQueue"), // comment col.
2055  sRemoteHost,
2056  JOB_NO_FLAGS,
2057  JOB_QUEUED,
2058  JobStartTime.toUTC());
2059 
2060  if (!bReturn)
2061  {
2062  LOG(VB_GENERAL, LOG_ERR, QString("%1 job wasn't queued because of a "
2063  "database error or because it was "
2064  "already running/stopping etc.")
2065  .arg(sJobName));
2066 
2067  return nReturn;
2068  }
2069 
2070  return JobQueue::GetJobID(jobType, ri.GetChanID(),
2071  ri.GetRecordingStartTime());
2072 }
2073 
2075 //
2077 
2079  bool AutoExpire,
2080  long BookmarkOffset,
2081  const QString &BookmarkOffsetType,
2082  bool Damaged,
2083  const QString &Description,
2084  uint Episode,
2085  const QString &Inetref,
2086  QDate OriginalAirDate,
2087  bool Preserve,
2088  uint Season,
2089  uint Stars,
2090  const QString &SubTitle,
2091  const QString &Title,
2092  bool Watched )
2093 
2094 {
2095  if (m_request->m_queries.size() < 2 || !HAS_PARAMv2("RecordedId"))
2096  {
2097  LOG(VB_GENERAL, LOG_ERR, "No RecordedId, or no parameters to change.");
2098  return false;
2099  }
2100 
2101  auto pi = ProgramInfo(RecordedId);
2102  auto ri = RecordingInfo(RecordedId);
2103 
2104  if (!ri.GetChanID())
2105  return false;
2106 
2107  if (HAS_PARAMv2("AutoExpire"))
2108  pi.SaveAutoExpire(AutoExpire ? kNormalAutoExpire :
2109  kDisableAutoExpire, false);
2110 
2111  if (HAS_PARAMv2("BookmarkOffset"))
2112  {
2113  uint64_t position =0;
2114 
2115  if (BookmarkOffsetType.toLower() == "position")
2116  {
2117  if (!ri.QueryPositionKeyFrame(&position, BookmarkOffset, true))
2118  return false;
2119  }
2120  else if (BookmarkOffsetType.toLower() == "duration")
2121  {
2122  if (!ri.QueryDurationKeyFrame(&position, BookmarkOffset, true))
2123  return false;
2124  }
2125  else
2126  position = BookmarkOffset;
2127 
2128  ri.SaveBookmark(position);
2129  }
2130 
2131  if (HAS_PARAMv2("Damaged"))
2132  pi.SaveVideoProperties(VID_DAMAGED, Damaged ? VID_DAMAGED : 0);
2133 
2134  if (HAS_PARAMv2("Description") ||
2135  HAS_PARAMv2("SubTitle") ||
2136  HAS_PARAMv2("Title"))
2137  {
2138 
2139  QString tmp_description;
2140  QString tmp_subtitle;
2141  QString tmp_title;
2142 
2143  if (HAS_PARAMv2("Description"))
2144  tmp_description = Description;
2145  else
2146  tmp_description = ri.GetDescription();
2147 
2148  if (HAS_PARAMv2("SubTitle"))
2149  tmp_subtitle = SubTitle;
2150  else
2151  tmp_subtitle = ri.GetSubtitle();
2152 
2153  if (HAS_PARAMv2("Title"))
2154  tmp_title = Title;
2155  else
2156  tmp_title = ri.GetTitle();
2157 
2158  ri.ApplyRecordRecTitleChange(tmp_title, tmp_subtitle, tmp_description);
2159  }
2160 
2161  if (HAS_PARAMv2("Episode") ||
2162  HAS_PARAMv2("Season"))
2163  {
2164  int tmp_episode = 0;
2165  int tmp_season = 0;
2166 
2167  if (HAS_PARAMv2("Episode"))
2168  tmp_episode = Episode;
2169  else
2170  tmp_episode = ri.GetEpisode();
2171 
2172  if (HAS_PARAMv2("Season"))
2173  tmp_season = Season;
2174  else
2175  tmp_season = ri.GetSeason();
2176 
2177  pi.SaveSeasonEpisode(tmp_season, tmp_episode);
2178  }
2179 
2180  if (HAS_PARAMv2("Inetref"))
2181  pi.SaveInetRef(Inetref);
2182 
2183  if (HAS_PARAMv2("OriginalAirDate"))
2184  {
2185  if (!OriginalAirDate.isValid())
2186  {
2187  LOG(VB_GENERAL, LOG_ERR, "Need valid OriginalAirDate yyyy-mm-dd.");
2188  return false;
2189  }
2190  ri.ApplyOriginalAirDateChange(OriginalAirDate);
2191  }
2192 
2193  if (HAS_PARAMv2("Preserve"))
2194  pi.SavePreserve(Preserve);
2195 
2196  if (HAS_PARAMv2("Stars"))
2197  {
2198  if (Stars > 10)
2199  {
2200  LOG(VB_GENERAL, LOG_ERR, "Recording stars can be 0 to 10.");
2201  return false;
2202  }
2203  ri.ApplyStarsChange(Stars * 0.1);
2204  }
2205 
2206  if (HAS_PARAMv2("Watched"))
2207  pi.SaveWatched(Watched);
2208 
2209  return true;
2210 }
MythHTTPService::HAS_PARAMv2
bool HAS_PARAMv2(const QString &p)
Definition: mythhttpservice.h:36
StorageGroup::getRecordingsGroups
static QStringList getRecordingsGroups(void)
Definition: storagegroup.cpp:789
RecordingInfo::GetRecgroupID
static uint GetRecgroupID(const QString &recGroup)
Temporary helper during transition from string to ID.
Definition: recordinginfo.cpp:1688
RecordingRule::m_channelid
int m_channelid
callsign?
Definition: recordingrule.h:99
V2Dvr::AllowReRecord
static bool AllowReRecord(int RecordedId)
Definition: v2dvr.cpp:719
MSqlBindings
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:101
RecordingRule::LoadByProgram
bool LoadByProgram(const ProgramInfo *proginfo)
Definition: recordingrule.cpp:168
Scheduler::kSortNextRecording
@ kSortNextRecording
Definition: scheduler.h:86
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:807
RecStatus::Type
Type
Definition: recordingstatus.h:16
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
RecordingRule::m_autoTranscode
bool m_autoTranscode
Definition: recordingrule.h:132
RecordingRule::m_enddate
QDate m_enddate
Definition: recordingrule.h:90
RecordingInfo::kDefaultRecGroup
@ kDefaultRecGroup
Definition: recordinginfo.h:191
RecordingRule::m_playGroup
QString m_playGroup
Definition: recordingrule.h:122
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:84
V2Dvr::RecStatusToString
static QString RecStatusToString(int RecStatus)
Definition: v2dvr.cpp:1907
RecordingRule::m_seriesid
QString m_seriesid
Definition: recordingrule.h:84
RecordingRule::m_parentRecID
int m_parentRecID
Definition: recordingrule.h:71
COMM_FLAG_NOT_FLAGGED
@ COMM_FLAG_NOT_FLAGGED
Definition: programtypes.h:122
RecordingInfo::QueryRecordedIdForKey
static bool QueryRecordedIdForKey(int &recordedid, uint chanid, const QDateTime &recstartts)
Definition: recordinginfo.cpp:944
V2InputList
Definition: v2inputList.h:20
V2Dvr::GetRecordedSeek
static V2CutList * GetRecordedSeek(int RecordedId, const QString &OffsetType)
Definition: v2dvr.cpp:994
RecordingInfo::ApplyNeverRecord
void ApplyNeverRecord(void)
Set this program to never be recorded by inserting 'history' for it into the database with a status o...
Definition: recordinginfo.cpp:907
V2Dvr::RecordedIdForPathname
static int RecordedIdForPathname(const QString &Pathname)
Definition: v2dvr.cpp:1897
backendcontext.h
V2Dvr::GetPlayGroupList
static QStringList GetPlayGroupList()
Definition: v2dvr.cpp:1214
V2FillProgramInfo
void V2FillProgramInfo(V2Program *pProgram, ProgramInfo *pInfo, bool bIncChannel, bool bDetails, bool bIncCast, bool bIncArtwork, bool bIncRecording)
Definition: v2serviceUtil.cpp:22
RecordingRule::m_description
QString m_description
Definition: recordingrule.h:81
RecordingRule::m_autoCommFlag
bool m_autoCommFlag
Definition: recordingrule.h:131
RecordingRule::m_inetref
QString m_inetref
Definition: recordingrule.h:87
V2Dvr::GetUpcomingList
static V2ProgramList * GetUpcomingList(int StartIndex, int Count, bool ShowAll, int RecordId, int RecStatus)
Definition: v2dvr.cpp:1343
RecordingInfo::kFoundProgram
@ kFoundProgram
Definition: recordinginfo.h:182
ProgramInfo::SaveBookmark
void SaveBookmark(uint64_t frame)
Clears any existing bookmark in DB and if frame is greater than 0 sets a new bookmark.
Definition: programinfo.cpp:2677
ProgramInfo::SetRecordingStatus
void SetRecordingStatus(RecStatus::Type status)
Definition: programinfo.h:580
MythCoreContext::GetScheduler
MythScheduler * GetScheduler(void)
Definition: mythcorecontext.cpp:1875
V2Dvr::GetRecordSchedule
static V2RecRule * GetRecordSchedule(uint RecordId, const QString &Template, int RecordedId, int ChanId, const QDateTime &StartTime, bool MakeOverride)
Definition: v2dvr.cpp:1793
RecordingRule::m_maxNewest
bool m_maxNewest
Definition: recordingrule.h:127
LoadProgramFromProgram
ProgramInfo * LoadProgramFromProgram(const uint chanid, const QDateTime &starttime)
Definition: programinfo.cpp:5794
RecordingRule::m_category
QString m_category
Definition: recordingrule.h:82
RecordingRule::Save
bool Save(bool sendSig=true)
Definition: recordingrule.cpp:388
JobQueue::QueueJob
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())
Definition: jobqueue.cpp:513
RecordingRule::m_starttime
QTime m_starttime
Definition: recordingrule.h:91
RecordingInfo::ApplyRecordStateChange
void ApplyRecordStateChange(RecordingType newstate, bool save=true)
Sets RecordingType of "record", creating "record" if it does not exist.
Definition: recordinginfo.cpp:573
Scheduler::kSortPriority
@ kSortPriority
Definition: scheduler.h:87
FillUpcomingList
int FillUpcomingList(QVariantList &list, QObject *parent, int &nStartIndex, int &nCount, bool bShowAll, int nRecordId, int nRecStatus)
Definition: v2serviceUtil.cpp:750
searchTypeFromString
RecSearchType searchTypeFromString(const QString &type)
Definition: recordingtypes.cpp:329
V2Dvr::GetRecordedList
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)
Definition: v2dvr.cpp:128
V2FillCommBreak
void V2FillCommBreak(V2CutList *pCutList, ProgramInfo *rInfo, int marktype)
Definition: v2serviceUtil.cpp:623
dupInFromString
RecordingDupInType dupInFromString(const QString &type)
Definition: recordingtypes.cpp:216
V2Dvr::DeleteRecording
static bool DeleteRecording(int RecordedId, int ChanId, const QDateTime &StartTime, bool ForceDelete, bool AllowRerecord)
Definition: v2dvr.cpp:590
Scheduler::GetAllScheduled
static void GetAllScheduled(QStringList &strList, SchedSortColumn sortBy=kSortTitle, bool ascending=true)
Returns all scheduled programs serialized into a QStringList.
Definition: scheduler.cpp:1843
RecordingInfo
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:35
gExpirer
AutoExpire * gExpirer
Definition: backendcontext.cpp:8
RecordingInfo::ForgetHistory
void ForgetHistory(void)
Forget the recording of a program so it will be recorded again.
Definition: recordinginfo.cpp:1461
ProgramInfo::QueryMarkup
void QueryMarkup(QVector< MarkupEntry > &mapMark, QVector< MarkupEntry > &mapSeek) const
Definition: programinfo.cpp:4562
programdata.h
ProgramInfo::GetRecordingID
uint GetRecordingID(void) const
Definition: programinfo.h:446
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
RecordingRule::m_title
QString m_title
Definition: recordingrule.h:77
JOB_COMMFLAG
@ JOB_COMMFLAG
Definition: jobqueue.h:81
ProgramInfo::QueryJobsRunning
static QMap< QString, bool > QueryJobsRunning(int type)
Definition: programinfo.cpp:5479
ProgramInfo::QueryPositionKeyFrame
bool QueryPositionKeyFrame(uint64_t *keyframe, uint64_t position, bool backwards) const
Definition: programinfo.cpp:4190
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:205
AutoExpire
Used to expire recordings to make space for new recordings.
Definition: autoexpire.h:60
JOB_NONE
@ JOB_NONE
Definition: jobqueue.h:77
V2ProgramList
Definition: v2programList.h:22
RecordingRule
Internal representation of a recording rule, mirrors the record table.
Definition: recordingrule.h:28
JobQueue::SafeDeleteJob
static bool SafeDeleteJob(int jobID, int jobType, int chanid, const QDateTime &recstartts)
Definition: jobqueue.cpp:876
RecordingDupMethodType
RecordingDupMethodType
Definition: recordingtypes.h:62
RecordingRule::m_endOffset
int m_endOffset
Definition: recordingrule.h:110
mythhttpmetaservice.h
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:608
V2Dvr::DupInToString
static QString DupInToString(const QString &DupIn)
Definition: v2dvr.cpp:1943
ProgramInfo::SaveCommFlagged
void SaveCommFlagged(CommFlagStatus flag)
Set "commflagged" field in "recorded" table to "flag".
Definition: programinfo.cpp:3341
RecStatus::Recorded
@ Recorded
Definition: recordingstatus.h:29
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
playgroup.h
V2Dvr::GetRecRuleFilterList
static V2RecRuleFilterList * GetRecRuleFilterList()
Definition: v2dvr.cpp:1223
DVR_HANDLE
#define DVR_HANDLE
Definition: v2dvr.h:40
ProgramInfo::QueryKeyFrameDuration
bool QueryKeyFrameDuration(uint64_t *duration, uint64_t keyframe, bool backwards) const
Definition: programinfo.cpp:4217
LoadFromRecorded
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)
Definition: programinfo.cpp:5996
AutoExpire::GetAllExpiring
void GetAllExpiring(QStringList &strList)
Gets the full list of programs that can expire in expiration order.
Definition: autoexpire.cpp:831
V2EncoderList
Definition: v2encoderList.h:20
RecordingRule::IsLoaded
bool IsLoaded() const
Definition: recordingrule.h:55
V2Dvr::RecTypeToDescription
static QString RecTypeToDescription(const QString &RecType)
Definition: v2dvr.cpp:1933
V2Dvr::GetSavedBookmark
static long GetSavedBookmark(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType)
Definition: v2dvr.cpp:769
V2Dvr::SetSavedBookmark
static bool SetSavedBookmark(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType, long Offset)
Definition: v2dvr.cpp:853
RecordingRule::m_dupIn
RecordingDupInType m_dupIn
Definition: recordingrule.h:114
RecordingRule::m_isInactive
bool m_isInactive
Recording rule is enabled?
Definition: recordingrule.h:74
v2dvr.h
RecordingRule::m_season
uint m_season
Definition: recordingrule.h:94
scheduler.h
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
V2Dvr::GetProgramCategories
static QStringList GetProgramCategories(bool OnlyRecorded)
Definition: v2dvr.cpp:1179
ProgramInfo::GetRecordingStartTime
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:404
ProgramInfo::IsWatched
bool IsWatched(void) const
Definition: programinfo.h:482
V2Dvr::GetConflictList
static V2ProgramList * GetConflictList(int StartIndex, int Count, int RecordId)
Definition: v2dvr.cpp:1321
DBCredits
std::vector< DBPerson > DBCredits
Definition: programdata.h:73
RecStatus::toString
static QString toString(RecStatus::Type recstatus, uint id)
Converts "recstatus" into a short (unreadable) string.
Definition: recordingstatus.cpp:40
JobQueue::InJobRunWindow
static bool InJobRunWindow(QDateTime jobstarttsRaw)
Definition: jobqueue.cpp:1652
ProgramInfo::IsPreserved
bool IsPreserved(void) const
Definition: programinfo.h:484
string_to_myth_category_type
ProgramInfo::CategoryType string_to_myth_category_type(const QString &category_type)
Definition: programinfo.cpp:137
ProgramInfo::QueryBookmark
uint64_t QueryBookmark(void) const
Gets any bookmark position in database, unless the ignore bookmark flag is set.
Definition: programinfo.cpp:2801
PlayGroup::GetNames
static QStringList GetNames(void)
Definition: playgroup.cpp:206
COMM_FLAG_DONE
@ COMM_FLAG_DONE
Definition: programtypes.h:123
V2Dvr::EnableRecordSchedule
static bool EnableRecordSchedule(uint RecordId)
Definition: v2dvr.cpp:1846
MythScheduler::GetRecording
virtual QMap< QString, ProgramInfo * > GetRecording(void) const =0
RecordingRule::Load
bool Load(bool asTemplate=false)
Load a single rule from the recorded table.
Definition: recordingrule.cpp:56
RecordingRule::m_startOffset
int m_startOffset
Definition: recordingrule.h:109
kDisableAutoExpire
@ kDisableAutoExpire
Definition: programtypes.h:195
RecordingDupInType
RecordingDupInType
Definition: recordingtypes.h:45
V2Dvr::DisableRecordSchedule
static bool DisableRecordSchedule(uint RecordId)
Definition: v2dvr.cpp:1866
V2FillInputInfo
void V2FillInputInfo(V2Input *input, const InputInfo &inputInfo)
Definition: v2serviceUtil.cpp:492
V2Dvr::RegisterCustomTypes
static void RegisterCustomTypes()
RecordingRule::m_episode
uint m_episode
Definition: recordingrule.h:95
autoexpire.h
ProgramInfo::MarkupEntry::type
int type
Definition: programinfo.h:694
V2Dvr::AddDontRecordSchedule
static bool AddDontRecordSchedule(int ChanId, const QDateTime &StartTime, bool NeverRecord)
Definition: v2dvr.cpp:1703
V2Dvr::UnDeleteRecording
static bool UnDeleteRecording(int RecordedId, int ChanId, const QDateTime &StartTime)
Definition: v2dvr.cpp:625
programinfo.h
CardUtil::GetAllInputInfo
static QList< InputInfo > GetAllInputInfo()
Definition: cardutil.cpp:1761
ProgramInfo::GetScheduledStartTime
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
Definition: programinfo.h:390
ProgramInfo::QueryRecordedIdFromPathname
static bool QueryRecordedIdFromPathname(const QString &pathname, uint &recordedid)
Definition: programinfo.cpp:1233
RecordingRule::IsValid
bool IsValid(QString &msg) const
Definition: recordingrule.cpp:855
kNormalAutoExpire
@ kNormalAutoExpire
Definition: programtypes.h:196
v2serviceUtil.h
v2titleInfoList.h
RecordingRule::m_autoUserJob4
bool m_autoUserJob4
Definition: recordingrule.h:136
V2FillRecRuleInfo
void V2FillRecRuleInfo(V2RecRule *pRecRule, RecordingRule *pRule)
Definition: v2serviceUtil.cpp:241
Scheduler::kSortType
@ kSortType
Definition: scheduler.h:87
MARK_DURATION_MS
@ MARK_DURATION_MS
Definition: programtypes.h:75
ProgramInfo::MarkupEntry::data
uint64_t data
Definition: programinfo.h:696
RecStatus::toDescription
static QString toDescription(Type recstatus, RecordingType rectype, const QDateTime &recstartts)
Converts "recstatus" into a long human readable description.
Definition: recordingstatus.cpp:188
FillEncoderList
void FillEncoderList(QVariantList &list, QObject *parent)
Definition: v2serviceUtil.cpp:687
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:540
RecordingRule::m_autoUserJob2
bool m_autoUserJob2
Definition: recordingrule.h:134
V2Dvr::GetRecorded
static V2Program * GetRecorded(int RecordedId, int ChanId, const QDateTime &StartTime)
Definition: v2dvr.cpp:368
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:227
Scheduler::kSortLastRecorded
@ kSortLastRecorded
Definition: scheduler.h:86
V2FillSeek
void V2FillSeek(V2CutList *pCutList, RecordingInfo *rInfo, MarkTypes marktype)
Definition: v2serviceUtil.cpp:669
RecordingRule::m_findtime
QTime m_findtime
Time for timeslot rules.
Definition: recordingrule.h:101
dupMethodFromString
RecordingDupMethodType dupMethodFromString(const QString &type)
Definition: recordingtypes.cpp:293
RecordingRule::m_lastRecorded
QDateTime m_lastRecorded
Definition: recordingrule.h:143
RecordingRule::m_autoExpire
bool m_autoExpire
Definition: recordingrule.h:126
markTypeFromString
MarkTypes markTypeFromString(const QString &str)
Definition: programtypes.cpp:68
RecordingRule::m_recProfile
QString m_recProfile
Definition: recordingrule.h:120
V2Dvr::UpdateRecordedWatchedStatus
static bool UpdateRecordedWatchedStatus(int RecordedId, int ChanId, const QDateTime &StartTime, bool Watched)
Definition: v2dvr.cpp:738
V2RecRuleFilterList
Definition: v2recRuleFilterList.h:12
RecordingRule::m_searchType
RecSearchType m_searchType
Definition: recordingrule.h:112
pginfolist_t
std::vector< ProgramInfo * > pginfolist_t
Definition: autoexpire.h:24
recTypeFromString
RecordingType recTypeFromString(const QString &type)
Definition: recordingtypes.cpp:101
RecordingRule::m_type
RecordingType m_type
Definition: recordingrule.h:111
Scheduler::kSortTitle
@ kSortTitle
Definition: scheduler.h:86
RecStatus::Conflict
@ Conflict
Definition: recordingstatus.h:39
V2Dvr::GetRecordScheduleList
static V2RecRuleList * GetRecordScheduleList(int StartIndex, int Count, const QString &Sort, bool Descending)
Definition: v2dvr.cpp:1731
RecordingRule::m_subtitle
QString m_subtitle
Definition: recordingrule.h:79
dupInFromStringAndBool
RecordingDupInType dupInFromStringAndBool(const QString &type, bool newEpisodesOnly)
Definition: recordingtypes.cpp:229
ProgramInfo::MarkupEntry
Definition: programinfo.h:692
V2CutList
Definition: v2cutList.h:21
storagegroup.h
V2Dvr::GetRecStorageGroupList
static QStringList GetRecStorageGroupList()
Definition: v2dvr.cpp:1205
V2Dvr::SetLastPlayPos
static bool SetLastPlayPos(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType, long Offset)
Definition: v2dvr.cpp:894
V2Dvr::GetRecordedMarkup
static V2MarkupList * GetRecordedMarkup(int RecordedId)
Definition: v2dvr.cpp:1024
jobqueue.h
RecordingRule::m_findday
int m_findday
Day of the week for once per week etc.
Definition: recordingrule.h:104
Scheduler::SchedSortColumn
SchedSortColumn
Definition: scheduler.h:86
RecordingRule::m_filter
unsigned m_filter
Definition: recordingrule.h:115
RecordingInfo::ReactivateRecording
void ReactivateRecording(void)
Asks the scheduler to restart this recording if possible.
Definition: recordinginfo.cpp:1331
V2Dvr::GetExpiringList
static V2ProgramList * GetExpiringList(int StartIndex, int Count)
Definition: v2dvr.cpp:84
kManualSearch
@ kManualSearch
Definition: recordingtypes.h:85
uint
unsigned int uint
Definition: compat.h:79
ProgramInfo::ProgramFlagsFromNames
void ProgramFlagsFromNames(const QString &names)
Definition: programinfo.cpp:1534
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:54
V2Dvr::DupMethodToString
static QString DupMethodToString(const QString &DupMethod)
Definition: v2dvr.cpp:1957
toDescription
QString toDescription(RecordingType rectype)
Converts "rectype" into a human readable description.
Definition: recordingtypes.cpp:50
RecordingInfo::LoadStatus
LoadStatus
Definition: recordinginfo.h:180
RecordingInfo::kNoProgram
@ kNoProgram
Definition: recordinginfo.h:181
V2CreateRecordingGroup
int V2CreateRecordingGroup(const QString &groupName)
Definition: v2serviceUtil.cpp:842
MythHTTPService
Definition: mythhttpservice.h:19
RecordingRule::m_maxEpisodes
int m_maxEpisodes
Definition: recordingrule.h:125
ProgramInfo::AudioPropertiesFromNames
static uint AudioPropertiesFromNames(const QString &names)
Definition: programinfo.cpp:1529
Stars
@ Stars
Definition: synaesthesia.h:26
RecordingRule::m_programid
QString m_programid
Definition: recordingrule.h:85
V2Dvr::AddRecordSchedule
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)
Definition: v2dvr.cpp:1367
ProgramInfo::SaveAutoExpire
void SaveAutoExpire(AutoExpireType autoExpire, bool updateDelete=false)
Set "autoexpire" field in "recorded" table to "autoExpire".
Definition: programinfo.cpp:3394
channelutil.h
V2Dvr::GetOldRecordedList
static V2ProgramList * GetOldRecordedList(bool Descending, int StartIndex, int Count, const QDateTime &StartTime, const QDateTime &EndTime, const QString &Title, const QString &SeriesId, int RecordId, const QString &Sort)
Definition: v2dvr.cpp:251
V2Dvr::RemoveRecordSchedule
static bool RemoveRecordSchedule(uint RecordId)
Definition: v2dvr.cpp:1688
ProgramInfo::SubtitleTypesFromNames
static uint SubtitleTypesFromNames(const QString &names)
Definition: programinfo.cpp:1519
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:34
RecordingRule::m_recGroupID
uint m_recGroupID
Definition: recordingrule.h:123
RecordingRule::m_endtime
QTime m_endtime
Definition: recordingrule.h:92
AutoDeleteDeque< ProgramInfo * >
V2Dvr::RescheduleRecordings
static bool RescheduleRecordings(void)
Definition: v2dvr.cpp:708
V2Dvr::GetTitleList
static QStringList GetTitleList(const QString &RecGroup)
Definition: v2dvr.cpp:1250
RecordingRule::m_storageGroup
QString m_storageGroup
Definition: recordingrule.h:121
ProgramInfo::GetChanID
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:372
RecordingRule::m_transcoder
int m_transcoder
Definition: recordingrule.h:130
RecordingRule::m_autoUserJob1
bool m_autoUserJob1
Definition: recordingrule.h:133
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
RecordingRule::LoadTemplate
bool LoadTemplate(const QString &title, const QString &category="Default", const QString &categoryType="Default")
Definition: recordingrule.cpp:274
RecordingRule::m_recordID
int m_recordID
Unique Recording Rule ID.
Definition: recordingrule.h:70
ProgramInfo::QueryKeyFramePosition
bool QueryKeyFramePosition(uint64_t *position, uint64_t keyframe, bool backwards) const
Definition: programinfo.cpp:4199
V2Dvr::ReactivateRecording
static bool ReactivateRecording(int RecordedId, int ChanId, const QDateTime &StartTime)
Definition: v2dvr.cpp:682
V2Dvr::RecTypeToString
static QString RecTypeToString(const QString &RecType)
Definition: v2dvr.cpp:1923
mythscheduler.h
mythcorecontext.h
V2Dvr::UpdateRecordSchedule
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)
Definition: v2dvr.cpp:1521
V2Dvr::GetLastPlayPos
static long GetLastPlayPos(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType)
Definition: v2dvr.cpp:811
JobQueue::GetJobTypeFromName
static int GetJobTypeFromName(const QString &name)
Definition: jobqueue.cpp:703
cardutil.h
kOverrideRecord
@ kOverrideRecord
Definition: recordingtypes.h:29
MARK_GOP_BYFRAME
@ MARK_GOP_BYFRAME
Definition: programtypes.h:65
RecordingInfo::InsertRecording
bool InsertRecording(const QString &ext, bool force_match=false)
Definition: recordinginfo.cpp:1042
RecordingRule::m_dupMethod
RecordingDupMethodType m_dupMethod
Definition: recordingrule.h:113
ProgramInfo::IsCommercialFlagged
bool IsCommercialFlagged(void) const
Definition: programinfo.h:478
V2Dvr::AddRecordedCredits
static bool AddRecordedCredits(int RecordedId, const QString &Cast)
Definition: v2dvr.cpp:392
JobQueue::GetJobID
static int GetJobID(int jobType, uint chanid, const QDateTime &recstartts)
Definition: jobqueue.cpp:643
V2Dvr::StopRecording
static bool StopRecording(int RecordedId)
Definition: v2dvr.cpp:656
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:883
kDupCheckNone
@ kDupCheckNone
Definition: recordingtypes.h:65
MarkTypes
MarkTypes
Definition: programtypes.h:48
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:17
ProgInfo
Definition: programdata.h:226
V2FillCutList
void V2FillCutList(V2CutList *pCutList, ProgramInfo *rInfo, int marktype)
Definition: v2serviceUtil.cpp:581
kSingleRecord
@ kSingleRecord
Definition: recordingtypes.h:23
V2Dvr::GetEncoderList
static V2EncoderList * GetEncoderList()
Definition: v2dvr.cpp:1127
V2Dvr::GetTitleInfoList
static V2TitleInfoList * GetTitleInfoList()
Definition: v2dvr.cpp:1286
ProgramInfo::QueryInUseMap
static QMap< QString, uint32_t > QueryInUseMap(void)
Definition: programinfo.cpp:5443
V2Markup
Definition: v2markup.h:21
ProgramInfo::SaveWatched
void SaveWatched(bool watchedFlag)
Set "watched" field in recorded/videometadata to "watchedFlag".
Definition: programinfo.cpp:3052
V2Dvr::DupInToDescription
static QString DupInToDescription(const QString &DupIn)
Definition: v2dvr.cpp:1950
RecList
std::deque< RecordingInfo * > RecList
Definition: mythscheduler.h:12
ProgramInfo::IsAutoExpirable
bool IsAutoExpirable(void) const
Definition: programinfo.h:483
V2Program
Definition: v2programAndChannel.h:105
V2Dvr::GetInputList
static V2InputList * GetInputList()
Definition: v2dvr.cpp:1138
marks
static const std::array< const mark, 16 > marks
Definition: lang.cpp:23
ProgramInfo::SendUpdateEvent
void SendUpdateEvent(void) const
Sends event out that the ProgramInfo should be reloaded.
Definition: programinfo.cpp:2755
tv_rec.h
ProgramInfo::SavePreserve
void SavePreserve(bool preserveEpisode)
Set "preserve" field in "recorded" table to "preserveEpisode".
Definition: programinfo.cpp:3367
ProgramInfo::MarkupEntry::isDataNull
bool isDataNull
Definition: programinfo.h:697
V2Dvr::DupMethodToDescription
static QString DupMethodToDescription(const QString &DupMethod)
Definition: v2dvr.cpp:1963
RecStatus
Definition: recordingstatus.h:11
V2Dvr::GetRecGroupList
static QStringList GetRecGroupList()
Definition: v2dvr.cpp:1156
V2Dvr::UpdateRecordedMetadata
bool UpdateRecordedMetadata(uint RecordedId, bool AutoExpire, long BookmarkOffset, const QString &BookmarkOffsetType, bool Damaged, const QString &Description, uint Episode, const QString &Inetref, QDate OriginalAirDate, bool Preserve, uint Season, uint Stars, const QString &SubTitle, const QString &Title, bool Watched)
Definition: v2dvr.cpp:2078
V2Dvr::RecordedIdForKey
static int RecordedIdForKey(int ChanId, const QDateTime &StartTime)
Definition: v2dvr.cpp:1886
JOB_NO_FLAGS
@ JOB_NO_FLAGS
Definition: jobqueue.h:61
LoadFromOldRecorded
bool LoadFromOldRecorded(ProgramList &destination, const QString &sql, const MSqlBindings &bindings)
Definition: programinfo.cpp:5830
RecordingRule::Delete
bool Delete(bool sendSig=true)
Definition: recordingrule.cpp:507
V2Dvr::GetRecordedCommBreak
static V2CutList * GetRecordedCommBreak(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType)
Definition: v2dvr.cpp:961
RecordingRule::MakeOverride
bool MakeOverride(void)
Definition: recordingrule.cpp:366
MARK_UNSET
@ MARK_UNSET
Definition: programtypes.h:51
ProgramInfo::MarkupEntry::frame
uint64_t frame
Definition: programinfo.h:695
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:836
ProgramInfo::SaveMarkup
void SaveMarkup(const QVector< MarkupEntry > &mapMark, const QVector< MarkupEntry > &mapSeek) const
Definition: programinfo.cpp:4643
MythHTTPService::m_request
HTTPRequest2 m_request
Definition: mythhttpservice.h:35
ProgramInfo::QueryLastPlayPos
uint64_t QueryLastPlayPos(void) const
Gets any lastplaypos position in database, unless the ignore lastplaypos flag is set.
Definition: programinfo.cpp:2828
MythCoreContext::GetBoolSettingOnHost
bool GetBoolSettingOnHost(const QString &key, const QString &host, bool defaultval=false)
Definition: mythcorecontext.cpp:933
musicbrainzngs.caa.hostname
string hostname
Definition: caa.py:17
V2RecRuleFilter
Definition: v2recRuleFilter.h:12
V2Dvr::GetRecordedCutList
static V2CutList * GetRecordedCutList(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType)
Definition: v2dvr.cpp:928
RecordingRule::m_station
QString m_station
Definition: recordingrule.h:98
ChannelUtil::GetChanNum
static QString GetChanNum(int chan_id)
Returns the channel-number string of the given channel.
Definition: channelutil.cpp:775
RecordingInfo::GetRecordingRule
RecordingRule * GetRecordingRule(void)
Returns the "record" field, creating it if necessary.
Definition: recordinginfo.cpp:928
V2RecRuleList
Definition: v2recRuleList.h:11
ProgramInfo::QueryDurationKeyFrame
bool QueryDurationKeyFrame(uint64_t *keyframe, uint64_t duration, bool backwards) const
Definition: programinfo.cpp:4208
RecordingRule::m_recPriority
int m_recPriority
Definition: recordingrule.h:107
build_compdb.filename
filename
Definition: build_compdb.py:21
RecordingRule::m_autoUserJob3
bool m_autoUserJob3
Definition: recordingrule.h:135
V2MarkupList
Definition: v2markupList.h:21
V2Dvr::RemoveRecorded
static bool RemoveRecorded(int RecordedId, int ChanId, const QDateTime &StartTime, bool ForceDelete, bool AllowRerecord)
Definition: v2dvr.cpp:581
Q_GLOBAL_STATIC_WITH_ARGS
Q_GLOBAL_STATIC_WITH_ARGS(MythHTTPMetaService, s_service,(DVR_HANDLE, V2Dvr::staticMetaObject, &V2Dvr::RegisterCustomTypes)) void V2Dvr
Definition: v2dvr.cpp:50
V2TitleInfoList
Definition: v2titleInfoList.h:20
ScheduledRecording::RescheduleMatch
static void RescheduleMatch(uint recordid, uint sourceid, uint mplexid, const QDateTime &maxstarttime, const QString &why)
Definition: scheduledrecording.h:17
MythCoreContext::dispatch
void dispatch(const MythEvent &event)
Definition: mythcorecontext.cpp:1723
RecordingType
RecordingType
Definition: recordingtypes.h:20
V2TitleInfo
Definition: v2titleInfo.h:20
V2Input
Definition: v2input.h:20
kDontRecord
@ kDontRecord
Definition: recordingtypes.h:30
V2Dvr::RecStatusToDescription
static QString RecStatusToDescription(int RecStatus, int RecType, const QDateTime &StartTime)
Definition: v2dvr.cpp:1913
MythHTTPMetaService
Definition: mythhttpmetaservice.h:10
RecordingRule::m_startdate
QDate m_startdate
Definition: recordingrule.h:89
RecordingRule::m_autoMetadataLookup
bool m_autoMetadataLookup
Definition: recordingrule.h:137
V2Dvr::AddRecordedProgram
static int AddRecordedProgram(const QString &Program)
Definition: v2dvr.cpp:421
ProgramInfo::HasPathname
bool HasPathname(void) const
Definition: programinfo.h:358
ProgramInfo::VideoPropertiesFromNames
static uint VideoPropertiesFromNames(const QString &names)
Definition: programinfo.cpp:1524
V2Dvr::ManageJobQueue
int ManageJobQueue(const QString &Action, const QString &JobName, int JobId, int RecordedId, QDateTime JobStartTime, QString RemoteHost, QString JobArgs)
Definition: v2dvr.cpp:1973
AutoDeleteDeque::size
size_t size(void) const
Definition: autodeletedeque.h:67
RecordingRule::m_prefInput
int m_prefInput
Definition: recordingrule.h:108
ProgramInfo::SaveLastPlayPos
void SaveLastPlayPos(uint64_t frame)
TODO Move to RecordingInfo.
Definition: programinfo.cpp:2714
V2jsonCastToCredits
DBCredits * V2jsonCastToCredits(const QJsonObject &cast)
Definition: v2serviceUtil.cpp:862
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:896
RecordingInfo::InsertFile
void InsertFile(void)
Definition: recordinginfo.cpp:1249
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:832
V2RecRule
Definition: v2recRule.h:12
JOB_USERJOB
@ JOB_USERJOB
Definition: jobqueue.h:85
V2Dvr::V2Dvr
V2Dvr()
Definition: v2dvr.cpp:79
V2Dvr::SetRecordedMarkup
static bool SetRecordedMarkup(int RecordedId, const QString &MarkupList)
Definition: v2dvr.cpp:1069