MythTV  master
dvr.cpp
Go to the documentation of this file.
1 // Program Name: dvr.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 #include <QMap>
27 #include <QRegExp>
28 
29 #include "dvr.h"
30 
31 #include "compat.h"
32 #include "mythversion.h"
33 #include "mythcorecontext.h"
34 #include "mythevent.h"
35 #include "scheduler.h"
36 #include "autoexpire.h"
37 #include "jobqueue.h"
38 #include "encoderlink.h"
39 #include "remoteutil.h"
40 #include "mythdate.h"
41 #include "recordinginfo.h"
42 #include "cardutil.h"
43 #include "inputinfo.h"
44 #include "programtypes.h"
45 #include "recordingtypes.h"
46 
47 #include "serviceUtil.h"
48 #include "mythscheduler.h"
49 #include "storagegroup.h"
50 #include "playgroup.h"
51 #include "recordingprofile.h"
52 
53 #include "scheduler.h"
54 #include "tv_rec.h"
55 
56 extern QMap<int, EncoderLink *> tvList;
57 extern AutoExpire *expirer;
58 
60 //
62 
64  int nStartIndex,
65  int nCount,
66  const QString &sTitleRegEx,
67  const QString &sRecGroup,
68  const QString &sStorageGroup,
69  const QString &sCategory,
70  const QString &sSort
71  )
72 {
73  QMap< QString, ProgramInfo* > recMap;
74 
76  recMap = gCoreContext->GetScheduler()->GetRecording();
77 
78  QMap< QString, uint32_t > inUseMap = ProgramInfo::QueryInUseMap();
79  QMap< QString, bool > isJobRunning= ProgramInfo::QueryJobsRunning(JOB_COMMFLAG);
80 
81  ProgramList progList;
82 
83  int desc = 1;
84  if (bDescending)
85  desc = -1;
86 
87  LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, desc, sSort );
88 
89  QMap< QString, ProgramInfo* >::iterator mit = recMap.begin();
90 
91  for (; mit != recMap.end(); mit = recMap.erase(mit))
92  delete *mit;
93 
94  // ----------------------------------------------------------------------
95  // Build Response
96  // ----------------------------------------------------------------------
97 
98  auto *pPrograms = new DTC::ProgramList();
99  int nAvailable = 0;
100 
101  int nMax = (nCount > 0) ? nCount : progList.size();
102 
103  nAvailable = 0;
104  nCount = 0;
105 
106  QRegExp rTitleRegEx = QRegExp(sTitleRegEx, Qt::CaseInsensitive);
107 
108  for (auto *pInfo : progList)
109  {
110  if (pInfo->IsDeletePending() ||
111  (!sTitleRegEx.isEmpty() && !pInfo->GetTitle().contains(rTitleRegEx)) ||
112  (!sRecGroup.isEmpty() && sRecGroup != pInfo->GetRecordingGroup()) ||
113  (!sStorageGroup.isEmpty() && sStorageGroup != pInfo->GetStorageGroup()) ||
114  (!sCategory.isEmpty() && sCategory != pInfo->GetCategory()))
115  continue;
116 
117  if ((nAvailable < nStartIndex) ||
118  (nCount >= nMax))
119  {
120  ++nAvailable;
121  continue;
122  }
123 
124  ++nAvailable;
125  ++nCount;
126 
127  DTC::Program *pProgram = pPrograms->AddNewProgram();
128 
129  FillProgramInfo( pProgram, pInfo, true );
130  }
131 
132  // ----------------------------------------------------------------------
133 
134  pPrograms->setStartIndex ( nStartIndex );
135  pPrograms->setCount ( nCount );
136  pPrograms->setTotalAvailable( nAvailable );
137  pPrograms->setAsOf ( MythDate::current() );
138  pPrograms->setVersion ( MYTH_BINARY_VERSION );
139  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
140 
141  return pPrograms;
142 }
143 
145 //
147 
149  int nStartIndex,
150  int nCount,
151  const QDateTime &sStartTime,
152  const QDateTime &sEndTime,
153  const QString &sTitle,
154  const QString &sSeriesId,
155  int nRecordId,
156  const QString &sSort)
157 {
158  if (!sStartTime.isNull() && !sStartTime.isValid())
159  throw QString("StartTime is invalid");
160 
161  if (!sEndTime.isNull() && !sEndTime.isValid())
162  throw QString("EndTime is invalid");
163 
164  const QDateTime& dtStartTime = sStartTime;
165  const QDateTime& dtEndTime = sEndTime;
166 
167  if (!sEndTime.isNull() && dtEndTime < dtStartTime)
168  throw QString("EndTime is before StartTime");
169 
170  // ----------------------------------------------------------------------
171  // Build SQL statement for Program Listing
172  // ----------------------------------------------------------------------
173 
174  ProgramList progList;
175  MSqlBindings bindings;
176  QString sSQL;
177 
178  if (!dtStartTime.isNull())
179  {
180  sSQL += " AND endtime >= :StartDate ";
181  bindings[":StartDate"] = dtStartTime;
182  }
183 
184  if (!dtEndTime.isNull())
185  {
186  sSQL += " AND starttime <= :EndDate ";
187  bindings[":EndDate"] = dtEndTime;
188  }
189 
190  QStringList clause;
191 
192  if (nRecordId > 0)
193  {
194  clause << "recordid = :RecordId";
195  bindings[":RecordId"] = nRecordId;
196  }
197 
198  if (!sTitle.isEmpty())
199  {
200  clause << "title = :Title";
201  bindings[":Title"] = sTitle;
202  }
203 
204  if (!sSeriesId.isEmpty())
205  {
206  clause << "seriesid = :SeriesId";
207  bindings[":SeriesId"] = sSeriesId;
208  }
209 
210  if (!clause.isEmpty())
211  {
212  sSQL += QString(" AND (%1) ").arg(clause.join(" OR "));
213  }
214 
215  if (sSort == "starttime")
216  sSQL += "ORDER BY starttime "; // NOLINT(bugprone-branch-clone)
217  else if (sSort == "title")
218  sSQL += "ORDER BY title ";
219  else
220  sSQL += "ORDER BY starttime ";
221 
222  if (bDescending)
223  sSQL += "DESC ";
224  else
225  sSQL += "ASC ";
226 
227  uint nTotalAvailable = (nStartIndex == 0) ? 1 : 0;
228  LoadFromOldRecorded( progList, sSQL, bindings,
229  (uint)nStartIndex, (uint)nCount, nTotalAvailable );
230 
231  // ----------------------------------------------------------------------
232  // Build Response
233  // ----------------------------------------------------------------------
234 
235  auto *pPrograms = new DTC::ProgramList();
236 
237  nCount = (int)progList.size();
238  int nEndIndex = (int)progList.size();
239 
240  for( int n = 0; n < nEndIndex; n++)
241  {
242  ProgramInfo *pInfo = progList[ n ];
243 
244  DTC::Program *pProgram = pPrograms->AddNewProgram();
245 
246  FillProgramInfo( pProgram, pInfo, true );
247  }
248 
249  // ----------------------------------------------------------------------
250 
251  pPrograms->setStartIndex ( nStartIndex );
252  pPrograms->setCount ( nCount );
253  pPrograms->setTotalAvailable( nTotalAvailable );
254  pPrograms->setAsOf ( MythDate::current() );
255  pPrograms->setVersion ( MYTH_BINARY_VERSION );
256  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
257 
258  return pPrograms;
259 }
260 
262 //
264 
266  int chanid, const QDateTime &recstarttsRaw)
267 {
268  if ((RecordedId <= 0) &&
269  (chanid <= 0 || !recstarttsRaw.isValid()))
270  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
271 
272  // TODO Should use RecordingInfo
273  ProgramInfo pi;
274  if (RecordedId > 0)
275  pi = ProgramInfo(RecordedId);
276  else
277  pi = ProgramInfo(chanid, recstarttsRaw.toUTC());
278 
279  auto *pProgram = new DTC::Program();
280  FillProgramInfo( pProgram, &pi, true );
281 
282  return pProgram;
283 }
284 
286 //
288 
289 bool Dvr::RemoveRecorded(int RecordedId,
290  int chanid, const QDateTime &recstarttsRaw,
291  bool forceDelete, bool allowRerecord)
292 {
293  return DeleteRecording(RecordedId, chanid, recstarttsRaw, forceDelete,
294  allowRerecord);
295 }
296 
297 
298 bool Dvr::DeleteRecording(int RecordedId,
299  int chanid, const QDateTime &recstarttsRaw,
300  bool forceDelete, bool allowRerecord)
301 {
302  if ((RecordedId <= 0) &&
303  (chanid <= 0 || !recstarttsRaw.isValid()))
304  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
305 
306  // TODO Should use RecordingInfo
307  ProgramInfo pi;
308  if (RecordedId > 0)
309  pi = ProgramInfo(RecordedId);
310  else
311  pi = ProgramInfo(chanid, recstarttsRaw.toUTC());
312 
313  if (pi.GetChanID() && pi.HasPathname())
314  {
315  QString cmd = QString("DELETE_RECORDING %1 %2 %3 %4")
316  .arg(pi.GetChanID())
318  .arg(forceDelete ? "FORCE" : "NO_FORCE")
319  .arg(allowRerecord ? "FORGET" : "NO_FORGET");
320  MythEvent me(cmd);
321 
322  gCoreContext->dispatch(me);
323  return true;
324  }
325 
326  return false;
327 }
328 
330 //
332 
333 bool Dvr::UnDeleteRecording(int RecordedId,
334  int chanid, const QDateTime &recstarttsRaw)
335 {
336  if ((RecordedId <= 0) &&
337  (chanid <= 0 || !recstarttsRaw.isValid()))
338  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
339 
340  RecordingInfo ri;
341  if (RecordedId > 0)
342  ri = RecordingInfo(RecordedId);
343  else
344  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
345 
346  if (ri.GetChanID() && ri.HasPathname())
347  {
348  QString cmd = QString("UNDELETE_RECORDING %1 %2")
349  .arg(ri.GetChanID())
351  MythEvent me(cmd);
352 
353  gCoreContext->dispatch(me);
354  return true;
355  }
356 
357  return false;
358 }
359 
361 //
363 
364 bool Dvr::StopRecording(int RecordedId)
365 {
366  if (RecordedId <= 0)
367  throw QString("RecordedId param is invalid.");
368 
369  RecordingInfo ri = RecordingInfo(RecordedId);
370 
371  if (ri.GetChanID())
372  {
373  QString cmd = QString("STOP_RECORDING %1 %2")
374  .arg(ri.GetChanID())
376  MythEvent me(cmd);
377 
378  gCoreContext->dispatch(me);
379  return true;
380  }
381  throw QString("RecordedId %1 not found").arg(RecordedId);
382 
383  return false;
384 }
385 
387 //
389 
390 bool Dvr::ReactivateRecording(int RecordedId,
391  int chanid, const QDateTime &recstarttsRaw)
392 {
393  if ((RecordedId <= 0) &&
394  (chanid <= 0 || !recstarttsRaw.isValid()))
395  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
396 
397  RecordingInfo ri;
398  if (RecordedId > 0)
399  ri = RecordingInfo(RecordedId);
400  else
401  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
402 
403  if (ri.GetChanID() && ri.HasPathname())
404  {
405  ri.ReactivateRecording();
406  return true;
407  }
408 
409  return false;
410 }
411 
413 //
415 
417 {
418  ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(),
419  "RescheduleRecordings");
420  return true;
421 }
422 
424 //
426 
427 bool Dvr::AllowReRecord ( int RecordedId )
428 {
429  if (RecordedId <= 0)
430  throw QString("RecordedId param is invalid.");
431 
432  RecordingInfo ri = RecordingInfo(RecordedId);
433 
434  if (!ri.GetChanID())
435  throw QString("RecordedId %1 not found").arg(RecordedId);
436 
437  ri.ForgetHistory();
438 
439  return true;
440 }
441 
443 //
445 
446 bool Dvr::UpdateRecordedWatchedStatus ( int RecordedId,
447  int chanid,
448  const QDateTime &recstarttsRaw,
449  bool watched)
450 {
451  if ((RecordedId <= 0) &&
452  (chanid <= 0 || !recstarttsRaw.isValid()))
453  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
454 
455  // TODO Should use RecordingInfo
456  ProgramInfo pi;
457  if (RecordedId > 0)
458  pi = ProgramInfo(RecordedId);
459  else
460  pi = ProgramInfo(chanid, recstarttsRaw.toUTC());
461 
462  if (pi.GetChanID() && pi.HasPathname())
463  {
464  pi.SaveWatched(watched);
465  return true;
466  }
467 
468  return false;
469 }
470 
472 //
474 
475 long Dvr::GetSavedBookmark( int RecordedId,
476  int chanid,
477  const QDateTime &recstarttsRaw,
478  const QString &offsettype )
479 {
480  if ((RecordedId <= 0) &&
481  (chanid <= 0 || !recstarttsRaw.isValid()))
482  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
483 
484  RecordingInfo ri;
485  if (RecordedId > 0)
486  ri = RecordingInfo(RecordedId);
487  else
488  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
489  uint64_t offset = 0;
490  bool isend=true;
491  uint64_t position = ri.QueryBookmark();
492  // if no bookmark return 0
493  if (position == 0)
494  return 0;
495  if (offsettype.toLower() == "position"){
496  // if bookmark cannot be converted to a keyframe we will
497  // just return the actual frame saved as the bookmark
498  if (ri.QueryKeyFramePosition(&offset, position, isend))
499  return offset;
500  }
501  if (offsettype.toLower() == "duration"){
502  if (ri.QueryKeyFrameDuration(&offset, position, isend))
503  return offset;
504  // If bookmark cannot be converted to a duration return -1
505  return -1;
506  }
507  return position;
508 }
509 
511 //
513 
514 bool Dvr::SetSavedBookmark( int RecordedId,
515  int chanid,
516  const QDateTime &recstarttsRaw,
517  const QString &offsettype,
518  long Offset )
519 {
520  if ((RecordedId <= 0) &&
521  (chanid <= 0 || !recstarttsRaw.isValid()))
522  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
523 
524  if (Offset < 0)
525  throw QString("Offset must be >= 0.");
526 
527  RecordingInfo ri;
528  if (RecordedId > 0)
529  ri = RecordingInfo(RecordedId);
530  else
531  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
532  uint64_t position = 0;
533  bool isend=true;
534  if (offsettype.toLower() == "position"){
535  if (!ri.QueryPositionKeyFrame(&position, Offset, isend))
536  return false;
537  }
538  else if (offsettype.toLower() == "duration"){
539  if (!ri.QueryDurationKeyFrame(&position, Offset, isend))
540  return false;
541  }
542  else
543  position = Offset;
544  ri.SaveBookmark(position);
545  return true;
546 }
547 
549 //
551 
553  int chanid,
554  const QDateTime &recstarttsRaw,
555  const QString &offsettype )
556 {
557  int marktype = 0;
558  if ((RecordedId <= 0) &&
559  (chanid <= 0 || !recstarttsRaw.isValid()))
560  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
561 
562  RecordingInfo ri;
563  if (RecordedId > 0)
564  ri = RecordingInfo(RecordedId);
565  else
566  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
567 
568  auto* pCutList = new DTC::CutList();
569  if (offsettype == "Position")
570  marktype = 1;
571  else if (offsettype == "Duration")
572  marktype = 2;
573  else
574  marktype = 0;
575 
576  FillCutList(pCutList, &ri, marktype);
577 
578  return pCutList;
579 }
580 
582 //
584 
586  int chanid,
587  const QDateTime &recstarttsRaw,
588  const QString &offsettype )
589 {
590  int marktype = 0;
591  if ((RecordedId <= 0) &&
592  (chanid <= 0 || !recstarttsRaw.isValid()))
593  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
594 
595  RecordingInfo ri;
596  if (RecordedId > 0)
597  ri = RecordingInfo(RecordedId);
598  else
599  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
600 
601  auto* pCutList = new DTC::CutList();
602  if (offsettype == "Position")
603  marktype = 1;
604  else if (offsettype == "Duration")
605  marktype = 2;
606  else
607  marktype = 0;
608 
609  FillCommBreak(pCutList, &ri, marktype);
610 
611  return pCutList;
612 }
613 
615 //
617 
619  const QString &offsettype )
620 {
621  MarkTypes marktype = MARK_UNSET;
622  if (RecordedId <= 0)
623  throw QString("Recorded ID appears invalid.");
624 
625  RecordingInfo ri;
626  ri = RecordingInfo(RecordedId);
627 
628  auto* pCutList = new DTC::CutList();
629  if (offsettype == "BYTES")
630  marktype = MARK_GOP_BYFRAME;
631  else if (offsettype == "DURATION")
632  marktype = MARK_DURATION_MS;
633  else
634  {
635  delete pCutList;
636  throw QString("Type must be 'BYTES' or 'DURATION'.");
637  }
638 
639  FillSeek(pCutList, &ri, marktype);
640 
641  return pCutList;
642 }
643 
645 //
647 
649  int nCount )
650 {
651  pginfolist_t infoList;
652 
653  if (expirer)
654  expirer->GetAllExpiring( infoList );
655 
656  // ----------------------------------------------------------------------
657  // Build Response
658  // ----------------------------------------------------------------------
659 
660  auto *pPrograms = new DTC::ProgramList();
661 
662  nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (int)infoList.size() ) : 0;
663  nCount = (nCount > 0) ? std::min( nCount, (int)infoList.size() ) : infoList.size();
664  int nEndIndex = std::min((nStartIndex + nCount), (int)infoList.size() );
665 
666  for( int n = nStartIndex; n < nEndIndex; n++)
667  {
668  ProgramInfo *pInfo = infoList[ n ];
669 
670  if (pInfo != nullptr)
671  {
672  DTC::Program *pProgram = pPrograms->AddNewProgram();
673 
674  FillProgramInfo( pProgram, pInfo, true );
675 
676  delete pInfo;
677  }
678  }
679 
680  // ----------------------------------------------------------------------
681 
682  pPrograms->setStartIndex ( nStartIndex );
683  pPrograms->setCount ( nCount );
684  pPrograms->setTotalAvailable( infoList.size() );
685  pPrograms->setAsOf ( MythDate::current() );
686  pPrograms->setVersion ( MYTH_BINARY_VERSION );
687  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
688 
689  return pPrograms;
690 }
691 
693 //
695 
697 {
698  auto* pList = new DTC::EncoderList();
699 
700  QReadLocker tvlocker(&TVRec::s_inputsLock);
701  QList<InputInfo> inputInfoList = CardUtil::GetAllInputInfo();
702  for (auto * elink : qAsConst(tvList))
703  {
704  if (elink != nullptr)
705  {
706  DTC::Encoder *pEncoder = pList->AddNewEncoder();
707 
708  pEncoder->setId ( elink->GetInputID() );
709  pEncoder->setState ( elink->GetState() );
710  pEncoder->setLocal ( elink->IsLocal() );
711  pEncoder->setConnected ( elink->IsConnected() );
712  pEncoder->setSleepStatus ( elink->GetSleepStatus() );
713  // pEncoder->setLowOnFreeSpace( elink->isLowOnFreeSpace());
714 
715  if (pEncoder->Local())
716  pEncoder->setHostName( gCoreContext->GetHostName() );
717  else
718  pEncoder->setHostName( elink->GetHostName() );
719 
720  for (const auto & inputInfo : qAsConst(inputInfoList))
721  {
722  if (inputInfo.m_inputId == static_cast<uint>(elink->GetInputID()))
723  {
724  DTC::Input *input = pEncoder->AddNewInput();
725  FillInputInfo(input, inputInfo);
726  }
727  }
728 
729  switch ( pEncoder->State() )
730  {
734  {
735  ProgramInfo *pInfo = elink->GetRecording();
736 
737  if (pInfo)
738  {
739  DTC::Program *pProgram = pEncoder->Recording();
740 
741  FillProgramInfo( pProgram, pInfo, true, true );
742 
743  delete pInfo;
744  }
745 
746  break;
747  }
748 
749  default:
750  break;
751  }
752  }
753  }
754  return pList;
755 }
756 
758 //
760 
762 {
763  auto *pList = new DTC::InputList();
764 
765  QList<InputInfo> inputInfoList = CardUtil::GetAllInputInfo();
766  for (const auto & inputInfo : qAsConst(inputInfoList))
767  {
768  DTC::Input *input = pList->AddNewInput();
769  FillInputInfo(input, inputInfo);
770  }
771 
772  return pList;
773 }
774 
776 //
778 
779 QStringList Dvr::GetRecGroupList()
780 {
782  query.prepare("SELECT recgroup FROM recgroups WHERE recgroup <> 'Deleted' "
783  "ORDER BY recgroup");
784 
785  QStringList result;
786  if (!query.exec())
787  {
788  MythDB::DBError("GetRecGroupList", query);
789  return result;
790  }
791 
792  while (query.next())
793  result << query.value(0).toString();
794 
795  return result;
796 }
797 
799 //
801 
802 QStringList Dvr::GetProgramCategories( bool OnlyRecorded )
803 {
805 
806  if (OnlyRecorded)
807  query.prepare("SELECT DISTINCT category FROM recorded ORDER BY category");
808  else
809  query.prepare("SELECT DISTINCT category FROM program ORDER BY category");
810 
811  QStringList result;
812  if (!query.exec())
813  {
814  MythDB::DBError("GetProgramCategories", query);
815  return result;
816  }
817 
818  while (query.next())
819  result << query.value(0).toString();
820 
821  return result;
822 }
823 
825 //
827 
829 {
831 }
832 
834 //
836 
838 {
839  return PlayGroup::GetNames();
840 }
841 
843 //
845 
847 {
848  auto* filterList = new DTC::RecRuleFilterList();
849 
851 
852  query.prepare("SELECT filterid, description, newruledefault "
853  "FROM recordfilter ORDER BY filterid");
854 
855  if (query.exec())
856  {
857  while (query.next())
858  {
859  DTC::RecRuleFilter* ruleFilter = filterList->AddNewRecRuleFilter();
860  ruleFilter->setId(query.value(0).toInt());
861  ruleFilter->setDescription(QObject::tr(query.value(1).toString()
862  .toUtf8().constData()));
863  }
864  }
865 
866  return filterList;
867 }
868 
870 //
872 
873 QStringList Dvr::GetTitleList(const QString& RecGroup)
874 {
876 
877  QString querystr = "SELECT DISTINCT title FROM recorded "
878  "WHERE deletepending = 0";
879 
880  if (!RecGroup.isEmpty())
881  querystr += " AND recgroup = :RECGROUP";
882  else
883  querystr += " AND recgroup != 'Deleted'";
884 
885  querystr += " ORDER BY title";
886 
887  query.prepare(querystr);
888 
889  if (!RecGroup.isEmpty())
890  query.bindValue(":RECGROUP", RecGroup);
891 
892  QStringList result;
893  if (!query.exec())
894  {
895  MythDB::DBError("GetTitleList recorded", query);
896  return result;
897  }
898 
899  while (query.next())
900  result << query.value(0).toString();
901 
902  return result;
903 }
904 
906 //
908 
910 {
912 
913  QString querystr = QString(
914  "SELECT title, inetref, count(title) as count "
915  " FROM recorded AS r "
916  " JOIN recgroups AS g ON r.recgroupid = g.recgroupid "
917  " WHERE g.recgroup NOT IN ('Deleted', 'LiveTV') "
918  " AND r.deletepending = 0 "
919  " GROUP BY title, inetref "
920  " ORDER BY title");
921 
922  query.prepare(querystr);
923 
924  auto *pTitleInfos = new DTC::TitleInfoList();
925  if (!query.exec())
926  {
927  MythDB::DBError("GetTitleList recorded", query);
928  return pTitleInfos;
929  }
930 
931  while (query.next())
932  {
933  DTC::TitleInfo *pTitleInfo = pTitleInfos->AddNewTitleInfo();
934 
935  pTitleInfo->setTitle(query.value(0).toString());
936  pTitleInfo->setInetref(query.value(1).toString());
937  pTitleInfo->setCount(query.value(2).toInt());
938  }
939 
940  return pTitleInfos;
941 }
942 
944 //
946 
948  int nCount,
949  bool bShowAll,
950  int nRecordId,
951  int nRecStatus )
952 {
953  RecordingList recordingList; // Auto-delete deque
954  RecList tmpList; // Standard deque, objects must be deleted
955 
956  if (nRecordId <= 0)
957  nRecordId = -1;
958 
959  // NOTE: Fetching this information directly from the schedule is
960  // significantly faster than using ProgramInfo::LoadFromScheduler()
961  auto *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler());
962  if (scheduler)
963  scheduler->GetAllPending(tmpList, nRecordId);
964 
965  // Sort the upcoming into only those which will record
966  // NOLINTNEXTLINE(modernize-loop-convert)
967  for (auto it = tmpList.begin(); it < tmpList.end(); ++it)
968  {
969  if ((nRecStatus != 0) &&
970  ((*it)->GetRecordingStatus() != nRecStatus))
971  {
972  delete *it;
973  *it = nullptr;
974  continue;
975  }
976 
977  if (!bShowAll && ((((*it)->GetRecordingStatus() >= RecStatus::Pending) &&
978  ((*it)->GetRecordingStatus() <= RecStatus::WillRecord)) ||
979  ((*it)->GetRecordingStatus() == RecStatus::Recorded) ||
980  ((*it)->GetRecordingStatus() == RecStatus::Conflict)) &&
981  ((*it)->GetRecordingEndTime() > MythDate::current()))
982  { // NOLINT(bugprone-branch-clone)
983  recordingList.push_back(new RecordingInfo(**it));
984  }
985  else if (bShowAll &&
986  ((*it)->GetRecordingEndTime() > MythDate::current()))
987  {
988  recordingList.push_back(new RecordingInfo(**it));
989  }
990 
991  delete *it;
992  *it = nullptr;
993  }
994 
995  // ----------------------------------------------------------------------
996  // Build Response
997  // ----------------------------------------------------------------------
998 
999  auto *pPrograms = new DTC::ProgramList();
1000 
1001  nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (int)recordingList.size() ) : 0;
1002  nCount = (nCount > 0) ? std::min( nCount, (int)recordingList.size() ) : recordingList.size();
1003  int nEndIndex = std::min((nStartIndex + nCount), (int)recordingList.size() );
1004 
1005  for( int n = nStartIndex; n < nEndIndex; n++)
1006  {
1007  ProgramInfo *pInfo = recordingList[ n ];
1008 
1009  DTC::Program *pProgram = pPrograms->AddNewProgram();
1010 
1011  FillProgramInfo( pProgram, pInfo, true );
1012  }
1013 
1014  // ----------------------------------------------------------------------
1015 
1016  pPrograms->setStartIndex ( nStartIndex );
1017  pPrograms->setCount ( nCount );
1018  pPrograms->setTotalAvailable( recordingList.size() );
1019  pPrograms->setAsOf ( MythDate::current() );
1020  pPrograms->setVersion ( MYTH_BINARY_VERSION );
1021  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1022 
1023  return pPrograms;
1024 }
1025 
1027 //
1029 
1031  int nCount,
1032  int nRecordId )
1033 {
1034  RecordingList recordingList; // Auto-delete deque
1035  RecList tmpList; // Standard deque, objects must be deleted
1036 
1037  if (nRecordId <= 0)
1038  nRecordId = -1;
1039 
1040  // NOTE: Fetching this information directly from the schedule is
1041  // significantly faster than using ProgramInfo::LoadFromScheduler()
1042  auto *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler());
1043  if (scheduler)
1044  scheduler->GetAllPending(tmpList, nRecordId);
1045 
1046  // Sort the upcoming into only those which are conflicts
1047  // NOLINTNEXTLINE(modernize-loop-convert)
1048  for (auto it = tmpList.begin(); it < tmpList.end(); ++it)
1049  {
1050  if (((*it)->GetRecordingStatus() == RecStatus::Conflict) &&
1051  ((*it)->GetRecordingStartTime() >= MythDate::current()))
1052  {
1053  recordingList.push_back(new RecordingInfo(**it));
1054  }
1055  delete *it;
1056  *it = nullptr;
1057  }
1058 
1059  // ----------------------------------------------------------------------
1060  // Build Response
1061  // ----------------------------------------------------------------------
1062 
1063  auto *pPrograms = new DTC::ProgramList();
1064 
1065  nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (int)recordingList.size() ) : 0;
1066  nCount = (nCount > 0) ? std::min( nCount, (int)recordingList.size() ) : recordingList.size();
1067  int nEndIndex = std::min((nStartIndex + nCount), (int)recordingList.size() );
1068 
1069  for( int n = nStartIndex; n < nEndIndex; n++)
1070  {
1071  ProgramInfo *pInfo = recordingList[ n ];
1072 
1073  DTC::Program *pProgram = pPrograms->AddNewProgram();
1074 
1075  FillProgramInfo( pProgram, pInfo, true );
1076  }
1077 
1078  // ----------------------------------------------------------------------
1079 
1080  pPrograms->setStartIndex ( nStartIndex );
1081  pPrograms->setCount ( nCount );
1082  pPrograms->setTotalAvailable( recordingList.size() );
1083  pPrograms->setAsOf ( MythDate::current() );
1084  pPrograms->setVersion ( MYTH_BINARY_VERSION );
1085  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1086 
1087  return pPrograms;
1088 }
1089 
1091  const QString& sTitle,
1092  const QString& sSubtitle,
1093  const QString& sDescription,
1094  const QString& sCategory,
1095  QDateTime recstarttsRaw,
1096  QDateTime recendtsRaw,
1097  const QString& sSeriesId,
1098  const QString& sProgramId,
1099  int nChanId,
1100  const QString& sStation,
1101  int nFindDay,
1102  QTime tFindTime,
1103  int nParentId,
1104  bool bInactive,
1105  uint nSeason,
1106  uint nEpisode,
1107  const QString& sInetref,
1108  QString sType,
1109  QString sSearchType,
1110  int nRecPriority,
1111  uint nPreferredInput,
1112  int nStartOffset,
1113  int nEndOffset,
1114  QDateTime lastrectsRaw,
1115  QString sDupMethod,
1116  QString sDupIn,
1117  bool bNewEpisOnly,
1118  uint nFilter,
1119  QString sRecProfile,
1120  QString sRecGroup,
1121  QString sStorageGroup,
1122  QString sPlayGroup,
1123  bool bAutoExpire,
1124  int nMaxEpisodes,
1125  bool bMaxNewest,
1126  bool bAutoCommflag,
1127  bool bAutoTranscode,
1128  bool bAutoMetaLookup,
1129  bool bAutoUserJob1,
1130  bool bAutoUserJob2,
1131  bool bAutoUserJob3,
1132  bool bAutoUserJob4,
1133  int nTranscoder)
1134 {
1135  QDateTime recstartts = recstarttsRaw.toUTC();
1136  QDateTime recendts = recendtsRaw.toUTC();
1137  QDateTime lastrects = lastrectsRaw.toUTC();
1138  RecordingRule rule;
1139  rule.LoadTemplate("Default");
1140 
1141  if (sType.isEmpty())
1142  sType = "single";
1143 
1144  if (sSearchType.isEmpty())
1145  sSearchType = "none";
1146 
1147  if (sDupMethod.isEmpty())
1148  sDupMethod = "subtitleanddescription";
1149 
1150  if (sDupIn.isEmpty())
1151  sDupIn = "all";
1152 
1153  rule.m_title = sTitle;
1154  rule.m_subtitle = sSubtitle;
1155  rule.m_description = sDescription;
1156 
1157  rule.m_startdate = recstartts.date();
1158  rule.m_starttime = recstartts.time();
1159  rule.m_enddate = recendts.date();
1160  rule.m_endtime = recendts.time();
1161 
1162  rule.m_type = recTypeFromString(sType);
1163  rule.m_searchType = searchTypeFromString(sSearchType);
1164  if (rule.m_searchType == kManualSearch)
1165  rule.m_dupMethod = kDupCheckNone;
1166  else
1167  rule.m_dupMethod = dupMethodFromString(sDupMethod);
1168  rule.m_dupIn = dupInFromStringAndBool(sDupIn, bNewEpisOnly);
1169 
1170  if (sRecProfile.isEmpty())
1171  sRecProfile = "Default";
1172 
1173  if (sRecGroup.isEmpty())
1174  sRecGroup = "Default";
1175 
1176  if (sStorageGroup.isEmpty())
1177  sStorageGroup = "Default";
1178 
1179  if (sPlayGroup.isEmpty())
1180  sPlayGroup = "Default";
1181 
1182  rule.m_category = sCategory;
1183  rule.m_seriesid = sSeriesId;
1184  rule.m_programid = sProgramId;
1185 
1186  rule.m_channelid = nChanId;
1187  rule.m_station = sStation;
1188 
1189  rule.m_findday = nFindDay;
1190  rule.m_findtime = tFindTime;
1191 
1192  rule.m_recProfile = sRecProfile;
1193  rule.m_recGroupID = RecordingInfo::GetRecgroupID(sRecGroup);
1194  if (rule.m_recGroupID == 0)
1195  {
1196  rule.m_recGroupID = CreateRecordingGroup(sRecGroup);
1197  if (rule.m_recGroupID <= 0)
1199  }
1200  rule.m_storageGroup = sStorageGroup;
1201  rule.m_playGroup = sPlayGroup;
1202 
1203  rule.m_parentRecID = nParentId;
1204  rule.m_isInactive = bInactive;
1205 
1206  rule.m_season = nSeason;
1207  rule.m_episode = nEpisode;
1208  rule.m_inetref = sInetref;
1209 
1210  rule.m_recPriority = nRecPriority;
1211  rule.m_prefInput = nPreferredInput;
1212  rule.m_startOffset = nStartOffset;
1213  rule.m_endOffset = nEndOffset;
1214  rule.m_filter = nFilter;
1215 
1216  rule.m_autoExpire = bAutoExpire;
1217  rule.m_maxEpisodes = nMaxEpisodes;
1218  rule.m_maxNewest = bMaxNewest;
1219 
1220  rule.m_autoCommFlag = bAutoCommflag;
1221  rule.m_autoTranscode = bAutoTranscode;
1222  rule.m_autoMetadataLookup = bAutoMetaLookup;
1223 
1224  rule.m_autoUserJob1 = bAutoUserJob1;
1225  rule.m_autoUserJob2 = bAutoUserJob2;
1226  rule.m_autoUserJob3 = bAutoUserJob3;
1227  rule.m_autoUserJob4 = bAutoUserJob4;
1228 
1229  rule.m_transcoder = nTranscoder;
1230 
1231  rule.m_lastRecorded = lastrects;
1232 
1233  QString msg;
1234  if (!rule.IsValid(msg))
1235  throw QString(msg);
1236 
1237  rule.Save();
1238 
1239  uint recid = rule.m_recordID;
1240 
1241  return recid;
1242 }
1243 
1245  QString sTitle,
1246  QString sSubtitle,
1247  QString sDescription,
1248  QString sCategory,
1249  QDateTime dStartTimeRaw,
1250  QDateTime dEndTimeRaw,
1251  QString sSeriesId,
1252  QString sProgramId,
1253  int nChanId,
1254  QString sStation,
1255  int nFindDay,
1256  QTime tFindTime,
1257  bool bInactive,
1258  uint nSeason,
1259  uint nEpisode,
1260  const QString& sInetref,
1261  QString sType,
1262  QString sSearchType,
1263  int nRecPriority,
1264  uint nPreferredInput,
1265  int nStartOffset,
1266  int nEndOffset,
1267  QString sDupMethod,
1268  QString sDupIn,
1269  bool bNewEpisOnly,
1270  uint nFilter,
1271  QString sRecProfile,
1272  QString sRecGroup,
1273  QString sStorageGroup,
1274  QString sPlayGroup,
1275  bool bAutoExpire,
1276  int nMaxEpisodes,
1277  bool bMaxNewest,
1278  bool bAutoCommflag,
1279  bool bAutoTranscode,
1280  bool bAutoMetaLookup,
1281  bool bAutoUserJob1,
1282  bool bAutoUserJob2,
1283  bool bAutoUserJob3,
1284  bool bAutoUserJob4,
1285  int nTranscoder)
1286 {
1287  if (nRecordId == 0 )
1288  throw QString("Record ID is invalid.");
1289 
1290  RecordingRule pRule;
1291  pRule.m_recordID = nRecordId;
1292  pRule.Load();
1293 
1294  if (!pRule.IsLoaded())
1295  throw QString("Record ID does not exist.");
1296 
1297  QDateTime recstartts = dStartTimeRaw.toUTC();
1298  QDateTime recendts = dEndTimeRaw.toUTC();
1299 
1300  pRule.m_isInactive = bInactive;
1301  if (sType.isEmpty())
1302  sType = "single";
1303 
1304  if (sSearchType.isEmpty())
1305  sSearchType = "none";
1306 
1307  if (sDupMethod.isEmpty())
1308  sDupMethod = "subtitleanddescription";
1309 
1310  if (sDupIn.isEmpty())
1311  sDupIn = "all";
1312 
1313  pRule.m_type = recTypeFromString(sType);
1314  pRule.m_searchType = searchTypeFromString(sSearchType);
1315  if (pRule.m_searchType == kManualSearch)
1316  pRule.m_dupMethod = kDupCheckNone;
1317  else
1318  pRule.m_dupMethod = dupMethodFromString(sDupMethod);
1319  pRule.m_dupIn = dupInFromStringAndBool(sDupIn, bNewEpisOnly);
1320 
1321  if (sRecProfile.isEmpty())
1322  sRecProfile = "Default";
1323 
1324  if (sRecGroup.isEmpty())
1325  sRecGroup = "Default";
1326 
1327  if (sStorageGroup.isEmpty())
1328  sStorageGroup = "Default";
1329 
1330  if (sPlayGroup.isEmpty())
1331  sPlayGroup = "Default";
1332 
1333  if (!sTitle.isEmpty())
1334  pRule.m_title = sTitle;
1335 
1336  if (!sSubtitle.isEmpty())
1337  pRule.m_subtitle = sSubtitle;
1338 
1339  if(!sDescription.isEmpty())
1340  pRule.m_description = sDescription;
1341 
1342  if (!sCategory.isEmpty())
1343  pRule.m_category = sCategory;
1344 
1345  if (!sSeriesId.isEmpty())
1346  pRule.m_seriesid = sSeriesId;
1347 
1348  if (!sProgramId.isEmpty())
1349  pRule.m_programid = sProgramId;
1350 
1351  if (nChanId)
1352  pRule.m_channelid = nChanId;
1353  if (!sStation.isEmpty())
1354  pRule.m_station = sStation;
1355 
1356  pRule.m_startdate = recstartts.date();
1357  pRule.m_starttime = recstartts.time();
1358  pRule.m_enddate = recendts.date();
1359  pRule.m_endtime = recendts.time();
1360 
1361  pRule.m_findday = nFindDay;
1362  pRule.m_findtime = tFindTime;
1363 
1364  pRule.m_recProfile = sRecProfile;
1365  pRule.m_recGroupID = RecordingInfo::GetRecgroupID(sRecGroup);
1366  if (pRule.m_recGroupID == 0)
1367  {
1368  pRule.m_recGroupID = CreateRecordingGroup(sRecGroup);
1369  if (pRule.m_recGroupID <= 0)
1371  }
1372  pRule.m_storageGroup = sStorageGroup;
1373  pRule.m_playGroup = sPlayGroup;
1374 
1375  pRule.m_isInactive = bInactive;
1376 
1377  pRule.m_season = nSeason;
1378  pRule.m_episode = nEpisode;
1379  pRule.m_inetref = sInetref;
1380 
1381  pRule.m_recPriority = nRecPriority;
1382  pRule.m_prefInput = nPreferredInput;
1383  pRule.m_startOffset = nStartOffset;
1384  pRule.m_endOffset = nEndOffset;
1385  pRule.m_filter = nFilter;
1386 
1387  pRule.m_autoExpire = bAutoExpire;
1388  pRule.m_maxEpisodes = nMaxEpisodes;
1389  pRule.m_maxNewest = bMaxNewest;
1390 
1391  pRule.m_autoCommFlag = bAutoCommflag;
1392  pRule.m_autoTranscode = bAutoTranscode;
1393  pRule.m_autoMetadataLookup = bAutoMetaLookup;
1394 
1395  pRule.m_autoUserJob1 = bAutoUserJob1;
1396  pRule.m_autoUserJob2 = bAutoUserJob2;
1397  pRule.m_autoUserJob3 = bAutoUserJob3;
1398  pRule.m_autoUserJob4 = bAutoUserJob4;
1399 
1400  pRule.m_transcoder = nTranscoder;
1401 
1402  QString msg;
1403  if (!pRule.IsValid(msg))
1404  throw QString(msg);
1405 
1406  bool bResult = pRule.Save();
1407 
1408  return bResult;
1409 }
1410 
1412 {
1413  bool bResult = false;
1414 
1415  if (nRecordId == 0 )
1416  throw QString("Record ID does not exist.");
1417 
1418  RecordingRule pRule;
1419  pRule.m_recordID = nRecordId;
1420 
1421  bResult = pRule.Delete();
1422 
1423  return bResult;
1424 }
1425 
1426 bool Dvr::AddDontRecordSchedule(int nChanId, const QDateTime &dStartTime,
1427  bool bNeverRecord)
1428 {
1429  bool bResult = true;
1430 
1431  if (nChanId <= 0 || !dStartTime.isValid())
1432  throw QString("Program does not exist.");
1433 
1434  ProgramInfo *pi = LoadProgramFromProgram(nChanId, dStartTime.toUTC());
1435 
1436  if (!pi)
1437  throw QString("Program does not exist.");
1438 
1439  // Why RecordingInfo instead of ProgramInfo? Good question ...
1440  RecordingInfo recInfo = RecordingInfo(*pi);
1441 
1442  delete pi;
1443 
1444  if (bNeverRecord)
1445  {
1446  recInfo.ApplyNeverRecord();
1447  }
1448  else
1450 
1451  return bResult;
1452 }
1453 
1455  int nCount,
1456  const QString &Sort,
1457  bool Descending )
1458 {
1460  if (Sort.toLower() == "lastrecorded")
1461  sortingColumn = Scheduler::kSortLastRecorded;
1462  else if (Sort.toLower() == "nextrecording")
1463  sortingColumn = Scheduler::kSortNextRecording;
1464  else if (Sort.toLower() == "title")
1465  sortingColumn = Scheduler::kSortTitle; // NOLINT(bugprone-branch-clone)
1466  else if (Sort.toLower() == "priority")
1467  sortingColumn = Scheduler::kSortPriority;
1468  else if (Sort.toLower() == "type")
1469  sortingColumn = Scheduler::kSortType;
1470  else
1471  sortingColumn = Scheduler::kSortTitle;
1472 
1473  RecList recList;
1474  Scheduler::GetAllScheduled(recList, sortingColumn, !Descending);
1475 
1476  // ----------------------------------------------------------------------
1477  // Build Response
1478  // ----------------------------------------------------------------------
1479 
1480  auto *pRecRules = new DTC::RecRuleList();
1481 
1482  nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (int)recList.size() ) : 0;
1483  nCount = (nCount > 0) ? std::min( nCount, (int)recList.size() ) : recList.size();
1484  int nEndIndex = std::min((nStartIndex + nCount), (int)recList.size() );
1485 
1486  for( int n = nStartIndex; n < nEndIndex; n++)
1487  {
1488  RecordingInfo *info = recList[n];
1489 
1490  if (info != nullptr)
1491  {
1492  DTC::RecRule *pRecRule = pRecRules->AddNewRecRule();
1493 
1494  FillRecRuleInfo( pRecRule, info->GetRecordingRule() );
1495  }
1496  }
1497 
1498  // ----------------------------------------------------------------------
1499 
1500  pRecRules->setStartIndex ( nStartIndex );
1501  pRecRules->setCount ( nCount );
1502  pRecRules->setTotalAvailable( recList.size() );
1503  pRecRules->setAsOf ( MythDate::current() );
1504  pRecRules->setVersion ( MYTH_BINARY_VERSION );
1505  pRecRules->setProtoVer ( MYTH_PROTO_VERSION );
1506 
1507  while (!recList.empty())
1508  {
1509  delete recList.back();
1510  recList.pop_back();
1511  }
1512 
1513  return pRecRules;
1514 }
1515 
1517  QString sTemplate,
1518  int nRecordedId,
1519  int nChanId,
1520  QDateTime dStartTimeRaw,
1521  bool bMakeOverride )
1522 {
1523  RecordingRule rule;
1524  QDateTime dStartTime = dStartTimeRaw.toUTC();
1525 
1526  if (nRecordId > 0)
1527  {
1528  rule.m_recordID = nRecordId;
1529  if (!rule.Load())
1530  throw QString("Record ID does not exist.");
1531  }
1532  else if (!sTemplate.isEmpty())
1533  {
1534  if (!rule.LoadTemplate(sTemplate))
1535  throw QString("Template does not exist.");
1536  }
1537  else if (nRecordedId > 0) // Loads from the Recorded/Recorded Program Table
1538  {
1539  // Despite the use of ProgramInfo, this only applies to Recordings.
1540  ProgramInfo recInfo(nRecordedId);
1541  if (!rule.LoadByProgram(&recInfo))
1542  throw QString("Recording does not exist");
1543  }
1544  else if (nChanId > 0 && dStartTime.isValid()) // Loads from Program Table, should NOT be used with recordings
1545  {
1546  // Despite the use of RecordingInfo, this only applies to programs in the
1547  // present or future, not to recordings? Confused yet?
1549  RecordingInfo info(nChanId, dStartTime, false, 0, &status);
1550  if (status != RecordingInfo::kFoundProgram)
1551  throw QString("Program does not exist.");
1552  RecordingRule *pRule = info.GetRecordingRule();
1553  if (bMakeOverride && rule.m_type != kSingleRecord &&
1554  rule.m_type != kOverrideRecord && rule.m_type != kDontRecord)
1555  pRule->MakeOverride();
1556  rule = *pRule;
1557  }
1558  else
1559  {
1560  throw QString("Invalid request.");
1561  }
1562 
1563  auto *pRecRule = new DTC::RecRule();
1564  FillRecRuleInfo( pRecRule, &rule );
1565 
1566  return pRecRule;
1567 }
1568 
1570 {
1571  bool bResult = false;
1572 
1573  if (nRecordId == 0 )
1574  throw QString("Record ID appears invalid.");
1575 
1576  RecordingRule pRule;
1577  pRule.m_recordID = nRecordId;
1578  pRule.Load();
1579 
1580  if (pRule.IsLoaded())
1581  {
1582  pRule.m_isInactive = false;
1583  bResult = pRule.Save();
1584  }
1585 
1586  return bResult;
1587 }
1588 
1590 {
1591  bool bResult = false;
1592 
1593  if (nRecordId == 0 )
1594  throw QString("Record ID appears invalid.");
1595 
1596  RecordingRule pRule;
1597  pRule.m_recordID = nRecordId;
1598  pRule.Load();
1599 
1600  if (pRule.IsLoaded())
1601  {
1602  pRule.m_isInactive = true;
1603  bResult = pRule.Save();
1604  }
1605 
1606  return bResult;
1607 }
1608 
1609 int Dvr::RecordedIdForKey(int chanid, const QDateTime &recstarttsRaw)
1610 {
1611  int recordedid = 0;
1612 
1613  if (!RecordingInfo::QueryRecordedIdForKey(recordedid, chanid,
1614  recstarttsRaw))
1615  return -1;
1616 
1617  return recordedid;
1618 }
1619 
1620 int Dvr::RecordedIdForPathname(const QString & pathname)
1621 {
1622  uint recordedid = 0;
1623 
1624  if (!ProgramInfo::QueryRecordedIdFromPathname(pathname, recordedid))
1625  return -1;
1626 
1627  return recordedid;
1628 }
1629 
1631 {
1632  auto type = static_cast<RecStatus::Type>(RecStatus);
1633  return RecStatus::toString(type);
1634 }
1635 
1636 QString Dvr::RecStatusToDescription(int RecStatus, int recType,
1637  const QDateTime &StartTime)
1638 {
1639  //if (!StartTime.isValid())
1640  // throw QString("StartTime appears invalid.");
1641  auto rsType = static_cast<RecStatus::Type>(RecStatus);
1642  auto recordingType = static_cast<RecordingType>(recType);
1643  return RecStatus::toDescription(rsType, recordingType, StartTime);
1644 }
1645 
1646 QString Dvr::RecTypeToString(QString recType)
1647 {
1648  bool ok = false;
1649  auto enumType = static_cast<RecordingType>(recType.toInt(&ok, 10));
1650  if (ok)
1651  return toString(enumType);
1652  // RecordingType type = static_cast<RecordingType>(recType);
1653  return toString(recTypeFromString(recType));
1654 }
1655 
1656 QString Dvr::RecTypeToDescription(QString recType)
1657 {
1658  bool ok = false;
1659  auto enumType = static_cast<RecordingType>(recType.toInt(&ok, 10));
1660  if (ok)
1661  return toDescription(enumType);
1662  // RecordingType type = static_cast<RecordingType>(recType);
1663  return toDescription(recTypeFromString(recType));
1664 }
1665 
1666 QString Dvr::DupInToString(QString DupIn)
1667 {
1668  // RecordingDupInType type= static_cast<RecordingDupInType>(DupIn);
1669  // return toString(type);
1670  return toString(dupInFromString(DupIn));
1671 }
1672 
1673 QString Dvr::DupInToDescription(QString DupIn)
1674 {
1675  // RecordingDupInType type= static_cast<RecordingDupInType>(DupIn);
1676  //return toDescription(type);
1677  return toDescription(dupInFromString(DupIn));
1678 }
1679 
1680 QString Dvr::DupMethodToString(QString DupMethod)
1681 {
1682  // RecordingDupMethodType method = static_cast<RecordingDupMethodType>(DupMethod);
1683  return toString(dupMethodFromString(DupMethod));
1684 }
1685 
1686 QString Dvr::DupMethodToDescription(QString DupMethod)
1687 {
1688  // RecordingDupMethodType method = static_cast<RecordingDupMethodType>(DupMethod);
1689  return toDescription(dupMethodFromString(DupMethod));
1690 }
1691 
1693 //
1695 
1696 int Dvr::ManageJobQueue( const QString &sAction,
1697  const QString &sJobName,
1698  int nJobId,
1699  int nRecordedId,
1700  QDateTime jobstarttsRaw,
1701  QString sRemoteHost,
1702  QString sJobArgs )
1703 {
1704  int nReturn = -1;
1705 
1706  if (!m_parsedParams.contains("jobname") &&
1707  !m_parsedParams.contains("recordedid") )
1708  {
1709  LOG(VB_GENERAL, LOG_ERR, "JobName and RecordedId are required.");
1710  return nReturn;
1711  }
1712 
1713  if (sRemoteHost.isEmpty())
1714  sRemoteHost = gCoreContext->GetHostName();
1715 
1716  int jobType = JobQueue::GetJobTypeFromName(sJobName);
1717 
1718  if (jobType == JOB_NONE)
1719  return nReturn;
1720 
1721  RecordingInfo ri = RecordingInfo(nRecordedId);
1722 
1723  if (!ri.GetChanID())
1724  return nReturn;
1725 
1726  if ( sAction == "Remove")
1727  {
1728  if (!m_parsedParams.contains("jobid") || nJobId < 0)
1729  {
1730  LOG(VB_GENERAL, LOG_ERR, "For Remove, a valid JobId is required.");
1731  return nReturn;
1732  }
1733 
1734  if (!JobQueue::SafeDeleteJob(nJobId, jobType, ri.GetChanID(),
1735  ri.GetRecordingStartTime()))
1736  return nReturn;
1737 
1738  return nJobId;
1739  }
1740 
1741  if ( sAction != "Add")
1742  {
1743  LOG(VB_GENERAL, LOG_ERR, QString("Illegal Action name '%1'. Use: Add, "
1744  "or Remove").arg(sAction));
1745  return nReturn;
1746  }
1747 
1748  if (((jobType & JOB_USERJOB) != 0) &&
1749  gCoreContext->GetSetting(sJobName, "").isEmpty())
1750  {
1751  LOG(VB_GENERAL, LOG_ERR, QString("%1 hasn't been defined.")
1752  .arg(sJobName));
1753  return nReturn;
1754  }
1755 
1756  if (!gCoreContext->GetBoolSettingOnHost(QString("JobAllow%1").arg(sJobName),
1757  sRemoteHost, false))
1758  {
1759  LOG(VB_GENERAL, LOG_ERR, QString("%1 hasn't been allowed on host %2.")
1760  .arg(sJobName).arg(sRemoteHost));
1761  return nReturn;
1762  }
1763 
1764  if (!jobstarttsRaw.isValid())
1765  jobstarttsRaw = QDateTime::currentDateTime();
1766 
1767  if (!JobQueue::InJobRunWindow(jobstarttsRaw))
1768  return nReturn;
1769 
1770  if (sJobArgs.isNull())
1771  sJobArgs = "";
1772 
1773  bool bReturn = JobQueue::QueueJob(jobType,
1774  ri.GetChanID(),
1775  ri.GetRecordingStartTime(),
1776  sJobArgs,
1777  QString("Dvr/ManageJobQueue"), // comment col.
1778  sRemoteHost,
1779  JOB_NO_FLAGS,
1780  JOB_QUEUED,
1781  jobstarttsRaw.toUTC());
1782 
1783  if (!bReturn)
1784  {
1785  LOG(VB_GENERAL, LOG_ERR, QString("%1 job wasn't queued because of a "
1786  "database error or because it was "
1787  "already running/stopping etc.")
1788  .arg(sJobName));
1789 
1790  return nReturn;
1791  }
1792 
1793  return JobQueue::GetJobID(jobType, ri.GetChanID(),
1794  ri.GetRecordingStartTime());
1795 }
StorageGroup::getRecordingsGroups
static QStringList getRecordingsGroups(void)
Definition: storagegroup.cpp:790
serviceUtil.h
RecordingInfo::GetRecgroupID
static uint GetRecgroupID(const QString &recGroup)
Temporary helper during transition from string to ID.
Definition: recordinginfo.cpp:1605
RecordingRule::m_channelid
int m_channelid
Definition: recordingrule.h:100
RecordingRule::LoadTemplate
bool LoadTemplate(const QString &category, const QString &categoryType="Default")
Definition: recordingrule.cpp:273
MSqlBindings
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:98
Scheduler
Definition: scheduler.h:46
RecordingRule::LoadByProgram
bool LoadByProgram(const ProgramInfo *proginfo)
Definition: recordingrule.cpp:168
Scheduler::kSortNextRecording
@ kSortNextRecording
Definition: scheduler.h:84
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
RecStatus::Type
Type
Definition: recStatus.h:16
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:126
RecordingRule::m_autoTranscode
bool m_autoTranscode
Definition: recordingrule.h:133
mythevent.h
FillProgramInfo
void FillProgramInfo(DTC::Program *pProgram, ProgramInfo *pInfo, bool bIncChannel, bool bDetails, bool bIncCast)
Definition: serviceUtil.cpp:44
RecordingRule::m_enddate
QDate m_enddate
Definition: recordingrule.h:92
RecordingInfo::kDefaultRecGroup
@ kDefaultRecGroup
Definition: recordinginfo.h:190
Dvr::GetRecordSchedule
DTC::RecRule * GetRecordSchedule(uint RecordId, QString Template, int nRecordedId, int ChanId, QDateTime dStartTimeRaw, bool MakeOverride) override
Definition: dvr.cpp:1516
RecordingRule::m_playGroup
QString m_playGroup
Definition: recordingrule.h:123
RecordingRule::m_seriesid
QString m_seriesid
Definition: recordingrule.h:86
RecordingRule::m_parentRecID
int m_parentRecID
Definition: recordingrule.h:73
RecordingInfo::QueryRecordedIdForKey
static bool QueryRecordedIdForKey(int &recordedid, uint chanid, const QDateTime &recstartts)
Definition: recordinginfo.cpp:891
FillRecRuleInfo
void FillRecRuleInfo(DTC::RecRule *pRecRule, RecordingRule *pRule)
Definition: serviceUtil.cpp:268
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:854
tvList
QMap< int, EncoderLink * > tvList
Definition: backendcontext.cpp:7
Dvr::GetRecRuleFilterList
DTC::RecRuleFilterList * GetRecRuleFilterList() override
Definition: dvr.cpp:846
RecordingRule::m_description
QString m_description
Definition: recordingrule.h:83
RecordingRule::m_autoCommFlag
bool m_autoCommFlag
Definition: recordingrule.h:132
RecordingRule::m_inetref
QString m_inetref
Definition: recordingrule.h:89
RecordingInfo::kFoundProgram
@ kFoundProgram
Definition: recordinginfo.h:181
ProgramInfo::SaveBookmark
void SaveBookmark(uint64_t frame)
TODO Move to RecordingInfo.
Definition: programinfo.cpp:2567
Dvr::RecStatusToDescription
QString RecStatusToDescription(int RecStatus, int RecType, const QDateTime &StartTime) override
Definition: dvr.cpp:1636
MythCoreContext::GetScheduler
MythScheduler * GetScheduler(void)
Definition: mythcorecontext.cpp:1882
RecordingRule::m_maxNewest
bool m_maxNewest
Definition: recordingrule.h:128
LoadProgramFromProgram
ProgramInfo * LoadProgramFromProgram(const uint chanid, const QDateTime &starttime)
Definition: programinfo.cpp:5610
Dvr::RecTypeToDescription
QString RecTypeToDescription(QString RecType) override
Definition: dvr.cpp:1656
RecordingRule::m_category
QString m_category
Definition: recordingrule.h:84
RecordingRule::Save
bool Save(bool sendSig=true)
Definition: recordingrule.cpp:383
DTC::Program
Definition: programAndChannel.h:146
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:519
RecordingRule::m_starttime
QTime m_starttime
Definition: recordingrule.h:93
RecordingInfo::ApplyRecordStateChange
void ApplyRecordStateChange(RecordingType newstate, bool save=true)
Sets RecordingType of "record", creating "record" if it does not exist.
Definition: recordinginfo.cpp:567
Dvr::RecTypeToString
QString RecTypeToString(QString RecType) override
Definition: dvr.cpp:1646
Scheduler::kSortPriority
@ kSortPriority
Definition: scheduler.h:85
Dvr::DupInToString
QString DupInToString(QString DupIn) override
Definition: dvr.cpp:1666
searchTypeFromString
RecSearchType searchTypeFromString(const QString &type)
Definition: recordingtypes.cpp:329
Dvr::GetProgramCategories
QStringList GetProgramCategories(bool OnlyRecorded) override
Definition: dvr.cpp:802
dupInFromString
RecordingDupInType dupInFromString(const QString &type)
Definition: recordingtypes.cpp:216
Scheduler::GetAllScheduled
static void GetAllScheduled(QStringList &strList, SchedSortColumn sortBy=kSortTitle, bool ascending=true)
Returns all scheduled programs serialized into a QStringList.
Definition: scheduler.cpp:1825
RecordingInfo
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:35
RecordingInfo::ForgetHistory
void ForgetHistory(void)
Forget the recording of a program so it will be recorded again.
Definition: recordinginfo.cpp:1378
DTC::Encoder::AddNewInput
Input * AddNewInput()
Definition: mythtv/libs/libmythservicecontracts/datacontracts/encoder.h:90
Dvr::AllowReRecord
bool AllowReRecord(int RecordedId) override
Definition: dvr.cpp:427
Dvr::GetTitleInfoList
DTC::TitleInfoList * GetTitleInfoList() override
Definition: dvr.cpp:909
DTC::Encoder::Recording
QObject * Recording
Definition: mythtv/libs/libmythservicecontracts/datacontracts/encoder.h:43
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:17
RecordingRule::m_title
QString m_title
Definition: recordingrule.h:79
JOB_COMMFLAG
@ JOB_COMMFLAG
Definition: jobqueue.h:73
Dvr::GetOldRecordedList
DTC::ProgramList * GetOldRecordedList(bool Descending, int StartIndex, int Count, const QDateTime &StartTime, const QDateTime &EndTime, const QString &Title, const QString &SeriesId, int RecordId, const QString &Sort) override
Definition: dvr.cpp:148
ProgramInfo::QueryJobsRunning
static QMap< QString, bool > QueryJobsRunning(int type)
Definition: programinfo.cpp:5295
ProgramInfo::QueryPositionKeyFrame
bool QueryPositionKeyFrame(uint64_t *keyframe, uint64_t position, bool backwards) const
Definition: programinfo.cpp:4012
Dvr::DupMethodToString
QString DupMethodToString(QString DupMethod) override
Definition: dvr.cpp:1680
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:198
arg
arg(title).arg(filename).arg(doDelete))
AutoExpire
Used to expire recordings to make space for new recordings.
Definition: autoexpire.h:61
DTC::TitleInfoList
Definition: titleInfoList.h:25
JOB_NONE
@ JOB_NONE
Definition: jobqueue.h:69
RecordingRule
Internal representation of a recording rule, mirrors the record table.
Definition: recordingrule.h:33
JobQueue::SafeDeleteJob
static bool SafeDeleteJob(int jobID, int jobType, int chanid, const QDateTime &recstartts)
Definition: jobqueue.cpp:882
RecordingRule::m_endOffset
int m_endOffset
Definition: recordingrule.h:112
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
RecStatus::Recorded
@ Recorded
Definition: recStatus.h:29
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
playgroup.h
ProgramInfo::QueryKeyFrameDuration
bool QueryKeyFrameDuration(uint64_t *duration, uint64_t keyframe, bool backwards) const
Definition: programinfo.cpp:4039
Dvr::GetInputList
DTC::InputList * GetInputList() override
Definition: dvr.cpp:761
AutoExpire::GetAllExpiring
void GetAllExpiring(QStringList &strList)
Gets the full list of programs that can expire in expiration order.
Definition: autoexpire.cpp:827
DTC::RecRuleFilterList
Definition: recRuleFilterList.h:17
Dvr::GetRecordedSeek
DTC::CutList * GetRecordedSeek(int RecordedId, const QString &OffsetType) override
Definition: dvr.cpp:618
RecordingRule::IsLoaded
bool IsLoaded() const
Definition: recordingrule.h:57
recordingtypes.h
RecordingRule::m_dupIn
RecordingDupInType m_dupIn
Definition: recordingrule.h:116
Dvr::RecordedIdForPathname
int RecordedIdForPathname(const QString &pathname) override
Definition: dvr.cpp:1620
RecordingRule::m_isInactive
bool m_isInactive
Recording rule is enabled?
Definition: recordingrule.h:76
expirer
AutoExpire * expirer
Definition: backendcontext.cpp:8
RecordingRule::m_season
uint m_season
Definition: recordingrule.h:96
remoteutil.h
Dvr::GetExpiringList
DTC::ProgramList * GetExpiringList(int StartIndex, int Count) override
Definition: dvr.cpp:648
scheduler.h
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
Dvr::GetRecordScheduleList
DTC::RecRuleList * GetRecordScheduleList(int StartIndex, int Count, const QString &Sort, bool Descending) override
Definition: dvr.cpp:1454
ProgramInfo::GetRecordingStartTime
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:402
mythversion.h
programtypes.h
JobQueue::InJobRunWindow
static bool InJobRunWindow(QDateTime jobstarttsRaw)
Definition: jobqueue.cpp:1656
ProgramInfo::QueryBookmark
uint64_t QueryBookmark(void) const
Gets any bookmark position in database, unless the ignore bookmark flag is set.
Definition: programinfo.cpp:2647
PlayGroup::GetNames
static QStringList GetNames(void)
Definition: playgroup.cpp:206
kState_WatchingRecording
@ kState_WatchingRecording
Watching Recording is the state for when we are watching an in progress recording,...
Definition: tv.h:80
MythScheduler::GetRecording
virtual QMap< QString, ProgramInfo * > GetRecording(void) const =0
RecStatus::WillRecord
@ WillRecord
Definition: recStatus.h:31
Dvr::RecStatusToString
QString RecStatusToString(int RecStatus) override
Definition: dvr.cpp:1630
RecordingRule::Load
bool Load(bool asTemplate=false)
Load a single rule from the recorded table.
Definition: recordingrule.cpp:58
RecordingRule::m_startOffset
int m_startOffset
Definition: recordingrule.h:111
toString
QString toString(MarkTypes type)
Definition: programtypes.cpp:26
RecordingRule::m_episode
uint m_episode
Definition: recordingrule.h:97
mythdate.h
autoexpire.h
Dvr::StopRecording
bool StopRecording(int RecordedId) override
Definition: dvr.cpp:364
CardUtil::GetAllInputInfo
static QList< InputInfo > GetAllInputInfo()
Definition: cardutil.cpp:1670
ProgramInfo::QueryRecordedIdFromPathname
static bool QueryRecordedIdFromPathname(const QString &pathname, uint &recordedid)
Definition: programinfo.cpp:1225
RecordingRule::IsValid
bool IsValid(QString &msg) const
Definition: recordingrule.cpp:849
Dvr::DupMethodToDescription
QString DupMethodToDescription(QString DupMethod) override
Definition: dvr.cpp:1686
Dvr::GetRecordedCutList
DTC::CutList * GetRecordedCutList(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, const QString &OffsetType) override
Definition: dvr.cpp:552
RecordingRule::m_autoUserJob4
bool m_autoUserJob4
Definition: recordingrule.h:137
Dvr::GetEncoderList
DTC::EncoderList * GetEncoderList() override
Definition: dvr.cpp:696
DTC::Input
Definition: input.h:25
Scheduler::kSortType
@ kSortType
Definition: scheduler.h:85
MARK_DURATION_MS
@ MARK_DURATION_MS
Definition: programtypes.h:74
RecStatus::toDescription
static QString toDescription(Type recstatus, RecordingType rectype, const QDateTime &recstartts)
Converts "recstatus" into a long human readable description.
Definition: recStatus.cpp:187
Dvr::RescheduleRecordings
bool RescheduleRecordings(void) override
Definition: dvr.cpp:416
FillCutList
void FillCutList(DTC::CutList *pCutList, RecordingInfo *rInfo, int marktype)
Definition: serviceUtil.cpp:626
Dvr::GetRecorded
DTC::Program * GetRecorded(int RecordedId, int ChanId, const QDateTime &recstarttsRaw) override
Definition: dvr.cpp:265
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
DTC::RecRuleList
Definition: recRuleList.h:16
compat.h
RecordingRule::m_autoUserJob2
bool m_autoUserJob2
Definition: recordingrule.h:135
Dvr::UnDeleteRecording
bool UnDeleteRecording(int RecordedId, int ChanId, const QDateTime &recstarttsRaw) override
Definition: dvr.cpp:333
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:178
Scheduler::kSortLastRecorded
@ kSortLastRecorded
Definition: scheduler.h:84
RecordingRule::m_findtime
QTime m_findtime
callsign?
Definition: recordingrule.h:103
dupMethodFromString
RecordingDupMethodType dupMethodFromString(const QString &type)
Definition: recordingtypes.cpp:293
Dvr::GetRecordedList
DTC::ProgramList * GetRecordedList(bool Descending, int StartIndex, int Count, const QString &TitleRegEx, const QString &RecGroup, const QString &StorageGroup, const QString &Category, const QString &Sort) override
Definition: dvr.cpp:63
RecordingRule::m_lastRecorded
QDateTime m_lastRecorded
Definition: recordingrule.h:144
RecordingRule::m_autoExpire
bool m_autoExpire
Definition: recordingrule.h:127
RecordingRule::m_recProfile
QString m_recProfile
Definition: recordingrule.h:121
RecordingRule::m_searchType
RecSearchType m_searchType
Definition: recordingrule.h:114
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:113
Scheduler::kSortTitle
@ kSortTitle
Definition: scheduler.h:84
RecStatus::Conflict
@ Conflict
Definition: recStatus.h:39
FillSeek
void FillSeek(DTC::CutList *pCutList, RecordingInfo *rInfo, MarkTypes marktype)
Definition: serviceUtil.cpp:718
Dvr::RemoveRecorded
bool RemoveRecorded(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, bool ForceDelete, bool AllowRerecord) override
Definition: dvr.cpp:289
RecordingRule::m_subtitle
QString m_subtitle
Definition: recordingrule.h:81
dupInFromStringAndBool
RecordingDupInType dupInFromStringAndBool(const QString &type, bool newEpisodesOnly)
Definition: recordingtypes.cpp:229
Dvr::UpdateRecordedWatchedStatus
bool UpdateRecordedWatchedStatus(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, bool Watched) override
Definition: dvr.cpp:446
Dvr::GetPlayGroupList
QStringList GetPlayGroupList() override
Definition: dvr.cpp:837
Service::m_parsedParams
QList< QString > m_parsedParams
Definition: service.h:67
storagegroup.h
jobqueue.h
RecordingRule::m_findday
int m_findday
Day of the week for once per week etc.
Definition: recordingrule.h:106
Scheduler::SchedSortColumn
SchedSortColumn
Definition: scheduler.h:84
RecordingRule::m_filter
unsigned m_filter
Definition: recordingrule.h:117
RecordingInfo::ReactivateRecording
void ReactivateRecording(void)
Asks the scheduler to restart this recording if possible.
Definition: recordinginfo.cpp:1248
TVRec::s_inputsLock
static QReadWriteLock s_inputsLock
Definition: tv_rec.h:426
kManualSearch
@ kManualSearch
Definition: recordingtypes.h:78
uint
unsigned int uint
Definition: compat.h:140
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:56
DTC::InputList
Definition: inputList.h:25
Dvr::DeleteRecording
bool DeleteRecording(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, bool ForceDelete, bool AllowRerecord) override
Definition: dvr.cpp:298
toDescription
QString toDescription(RecordingType rectype)
Converts "rectype" into a human readable description.
Definition: recordingtypes.cpp:50
dvr.h
RecordingInfo::LoadStatus
LoadStatus
Definition: recordinginfo.h:179
Dvr::RecordedIdForKey
int RecordedIdForKey(int ChanId, const QDateTime &recstarttsRaw) override
Definition: dvr.cpp:1609
RecordingInfo::kNoProgram
@ kNoProgram
Definition: recordinginfo.h:180
RecordingRule::m_maxEpisodes
int m_maxEpisodes
Definition: recordingrule.h:126
RecordingRule::m_programid
QString m_programid
Definition: recordingrule.h:87
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)
Definition: programinfo.cpp:5810
Dvr::GetRecStorageGroupList
QStringList GetRecStorageGroupList() override
Definition: dvr.cpp:828
RecStatus::Pending
@ Pending
Definition: recStatus.h:17
RecordingRule::m_recGroupID
uint m_recGroupID
Definition: recordingrule.h:124
RecordingRule::m_endtime
QTime m_endtime
Definition: recordingrule.h:94
Dvr::AddDontRecordSchedule
bool AddDontRecordSchedule(int ChanId, const QDateTime &StartTime, bool NeverRecord) override
Definition: dvr.cpp:1426
AutoDeleteDeque< ProgramInfo * >
Dvr::GetUpcomingList
DTC::ProgramList * GetUpcomingList(int StartIndex, int Count, bool ShowAll, int RecordId, int RecStatus) override
Definition: dvr.cpp:947
MYTH_BINARY_VERSION
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
Definition: mythversion.h:15
ProgramList
AutoDeleteDeque< ProgramInfo * > ProgramList
Definition: programinfo.h:31
recordinginfo.h
MYTH_PROTO_VERSION
#define MYTH_PROTO_VERSION
Increment this whenever the MythTV network protocol changes.
Definition: mythversion.h:47
RecordingRule::m_storageGroup
QString m_storageGroup
Definition: recordingrule.h:122
ProgramInfo::GetChanID
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:370
RecordingRule::m_transcoder
int m_transcoder
Definition: recordingrule.h:131
RecordingRule::m_autoUserJob1
bool m_autoUserJob1
Definition: recordingrule.h:134
AutoDeleteDeque::push_back
void push_back(T info)
Definition: autodeletedeque.h:69
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:68
Dvr::DisableRecordSchedule
bool DisableRecordSchedule(uint RecordId) override
Definition: dvr.cpp:1589
RecordingRule::m_recordID
int m_recordID
Unique Recording Rule ID.
Definition: recordingrule.h:72
ProgramInfo::QueryKeyFramePosition
bool QueryKeyFramePosition(uint64_t *position, uint64_t keyframe, bool backwards) const
Definition: programinfo.cpp:4021
mythscheduler.h
mythcorecontext.h
JobQueue::GetJobTypeFromName
static int GetJobTypeFromName(const QString &name)
Definition: jobqueue.cpp:709
cardutil.h
kOverrideRecord
@ kOverrideRecord
Definition: recordingtypes.h:28
MARK_GOP_BYFRAME
@ MARK_GOP_BYFRAME
Definition: programtypes.h:64
DTC::TitleInfo
Definition: titleInfo.h:25
DTC::RecRule
Definition: recRule.h:16
RecordingRule::m_dupMethod
RecordingDupMethodType m_dupMethod
Definition: recordingrule.h:115
FillCommBreak
void FillCommBreak(DTC::CutList *pCutList, RecordingInfo *rInfo, int marktype)
Definition: serviceUtil.cpp:672
JobQueue::GetJobID
static int GetJobID(int jobType, uint chanid, const QDateTime &recstartts)
Definition: jobqueue.cpp:649
Dvr::ReactivateRecording
bool ReactivateRecording(int RecordedId, int ChanId, const QDateTime &recstarttsRaw) override
Definition: dvr.cpp:390
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:864
kDupCheckNone
@ kDupCheckNone
Definition: recordingtypes.h:60
MarkTypes
MarkTypes
Definition: programtypes.h:48
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:14
Dvr::RemoveRecordSchedule
bool RemoveRecordSchedule(uint RecordId) override
Definition: dvr.cpp:1411
DTC::Encoder::Local
bool Local
Definition: mythtv/libs/libmythservicecontracts/datacontracts/encoder.h:36
kSingleRecord
@ kSingleRecord
Definition: recordingtypes.h:22
ProgramInfo::QueryInUseMap
static QMap< QString, uint32_t > QueryInUseMap(void)
Definition: programinfo.cpp:5259
Dvr::AddRecordSchedule
uint AddRecordSchedule(const QString &Title, const QString &Subtitle, const QString &Description, const QString &Category, QDateTime recstarttsRaw, QDateTime recendtsRaw, const QString &SeriesId, const QString &ProgramId, int ChanId, const QString &Station, int FindDay, QTime FindTime, int ParentId, bool Inactive, uint Season, uint Episode, const QString &Inetref, QString Type, QString SearchType, int RecPriority, uint PreferredInput, int StartOffset, int EndOffset, QDateTime lastrectsRaw, QString DupMethod, QString DupIn, bool NewEpisOnly, uint Filter, QString RecProfile, QString RecGroup, QString StorageGroup, QString PlayGroup, bool AutoExpire, int MaxEpisodes, bool MaxNewest, bool AutoCommflag, bool AutoTranscode, bool AutoMetaLookup, bool AutoUserJob1, bool AutoUserJob2, bool AutoUserJob3, bool AutoUserJob4, int Transcoder) override
Definition: dvr.cpp:1090
ProgramInfo::SaveWatched
void SaveWatched(bool watchedFlag)
Set "watched" field in recorded/videometadata to "watchedFlag".
Definition: programinfo.cpp:2871
RecList
std::deque< RecordingInfo * > RecList
Definition: mythscheduler.h:12
Dvr::GetTitleList
QStringList GetTitleList(const QString &RecGroup) override
Definition: dvr.cpp:873
DTC::Encoder::State
int State
Definition: mythtv/libs/libmythservicecontracts/datacontracts/encoder.h:38
tv_rec.h
kState_WatchingLiveTV
@ kState_WatchingLiveTV
Watching LiveTV is the state for when we are watching a recording and the user has control over the c...
Definition: tv.h:63
inputinfo.h
Dvr::GetRecGroupList
QStringList GetRecGroupList() override
Definition: dvr.cpp:779
RecStatus
Definition: recStatus.h:12
Dvr::SetSavedBookmark
bool SetSavedBookmark(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, const QString &OffsetType, long Offset) override
Definition: dvr.cpp:514
CreateRecordingGroup
int CreateRecordingGroup(const QString &groupName)
Definition: serviceUtil.cpp:736
JOB_NO_FLAGS
@ JOB_NO_FLAGS
Definition: jobqueue.h:53
LoadFromOldRecorded
bool LoadFromOldRecorded(ProgramList &destination, const QString &sql, const MSqlBindings &bindings)
Definition: programinfo.cpp:5646
RecordingRule::Delete
bool Delete(bool sendSig=true)
Definition: recordingrule.cpp:501
RecordingRule::MakeOverride
bool MakeOverride(void)
Definition: recordingrule.cpp:361
MARK_UNSET
@ MARK_UNSET
Definition: programtypes.h:50
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:855
Scheduler::GetAllPending
bool GetAllPending(RecList &retList, int recRuleId=0) const
Definition: scheduler.cpp:1733
recordingprofile.h
Dvr::ManageJobQueue
int ManageJobQueue(const QString &Action, const QString &JobName, int JobId, int RecordedId, QDateTime jobstarttsRaw, QString RemoteHost, QString JobArgs) override
Definition: dvr.cpp:1696
DTC::ProgramList
Definition: programList.h:27
MythCoreContext::GetBoolSettingOnHost
bool GetBoolSettingOnHost(const QString &key, const QString &host, bool defaultval=false)
Definition: mythcorecontext.cpp:952
Dvr::DupInToDescription
QString DupInToDescription(QString DupIn) override
Definition: dvr.cpp:1673
RecStatus::toString
static QString toString(Type recstatus, uint id)
Converts "recstatus" into a short (unreadable) string.
Definition: recStatus.cpp:39
RecordingRule::m_station
QString m_station
Definition: recordingrule.h:101
Dvr::GetConflictList
DTC::ProgramList * GetConflictList(int StartIndex, int Count, int RecordId) override
Definition: dvr.cpp:1030
Dvr::GetRecordedCommBreak
DTC::CutList * GetRecordedCommBreak(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, const QString &OffsetType) override
Definition: dvr.cpp:585
RecordingInfo::GetRecordingRule
RecordingRule * GetRecordingRule(void)
Returns the "record" field, creating it if necessary.
Definition: recordinginfo.cpp:875
DTC::Encoder
Definition: mythtv/libs/libmythservicecontracts/datacontracts/encoder.h:28
ProgramInfo::QueryDurationKeyFrame
bool QueryDurationKeyFrame(uint64_t *keyframe, uint64_t duration, bool backwards) const
Definition: programinfo.cpp:4030
RecordingRule::m_recPriority
int m_recPriority
Definition: recordingrule.h:109
Dvr::EnableRecordSchedule
bool EnableRecordSchedule(uint RecordId) override
Definition: dvr.cpp:1569
RecordingRule::m_autoUserJob3
bool m_autoUserJob3
Definition: recordingrule.h:136
DTC::RecRuleFilter
Definition: recRuleFilter.h:16
ScheduledRecording::RescheduleMatch
static void RescheduleMatch(uint recordid, uint sourceid, uint mplexid, const QDateTime &maxstarttime, const QString &why)
Definition: scheduledrecording.h:17
query
MSqlQuery query(MSqlQuery::InitCon())
MythCoreContext::dispatch
void dispatch(const MythEvent &event)
Definition: mythcorecontext.cpp:1730
DTC::EncoderList
Definition: encoderList.h:25
RecordingType
RecordingType
Definition: recordingtypes.h:20
kState_RecordingOnly
@ kState_RecordingOnly
Recording Only is a TVRec only state for when we are recording a program, but there is no one current...
Definition: tv.h:84
Dvr::GetSavedBookmark
long GetSavedBookmark(int RecordedId, int ChanId, const QDateTime &recstarttsRaw, const QString &OffsetType) override
Definition: dvr.cpp:475
Dvr::UpdateRecordSchedule
bool UpdateRecordSchedule(uint RecordId, QString Title, QString Subtitle, QString Description, QString Category, QDateTime dStartTimeRaw, QDateTime dEndTimeRaw, QString SeriesId, QString ProgramId, int ChanId, QString Station, int FindDay, QTime FindTime, bool Inactive, uint Season, uint Episode, const QString &Inetref, QString Type, QString SearchType, int RecPriority, uint PreferredInput, int StartOffset, int EndOffset, QString DupMethod, QString DupIn, bool NewEpisOnly, uint Filter, QString RecProfile, QString RecGroup, QString StorageGroup, QString PlayGroup, bool AutoExpire, int MaxEpisodes, bool MaxNewest, bool AutoCommflag, bool AutoTranscode, bool AutoMetaLookup, bool AutoUserJob1, bool AutoUserJob2, bool AutoUserJob3, bool AutoUserJob4, int Transcoder) override
Definition: dvr.cpp:1244
kDontRecord
@ kDontRecord
Definition: recordingtypes.h:29
RecordingRule::m_startdate
QDate m_startdate
Definition: recordingrule.h:91
RecordingRule::m_autoMetadataLookup
bool m_autoMetadataLookup
Definition: recordingrule.h:138
ProgramInfo::HasPathname
bool HasPathname(void) const
Definition: programinfo.h:356
AutoDeleteDeque::size
size_t size(void) const
Definition: autodeletedeque.h:67
RecordingRule::m_prefInput
int m_prefInput
Definition: recordingrule.h:110
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:915
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:808
JOB_USERJOB
@ JOB_USERJOB
Definition: jobqueue.h:77
FillInputInfo
void FillInputInfo(DTC::Input *input, const InputInfo &inputInfo)
Definition: serviceUtil.cpp:531
DTC::CutList
Definition: cutList.h:26