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 
55 extern QMap<int, EncoderLink *> tvList;
56 extern AutoExpire *expirer;
57 
59 //
61 
63  int nStartIndex,
64  int nCount,
65  const QString &sTitleRegEx,
66  const QString &sRecGroup,
67  const QString &sStorageGroup )
68 {
69  QMap< QString, ProgramInfo* > recMap;
70 
72  recMap = gCoreContext->GetScheduler()->GetRecording();
73 
74  QMap< QString, uint32_t > inUseMap = ProgramInfo::QueryInUseMap();
75  QMap< QString, bool > isJobRunning= ProgramInfo::QueryJobsRunning(JOB_COMMFLAG);
76 
77  ProgramList progList;
78 
79  int desc = 1;
80  if (bDescending)
81  desc = -1;
82 
83  LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, desc );
84 
85  QMap< QString, ProgramInfo* >::iterator mit = recMap.begin();
86 
87  for (; mit != recMap.end(); mit = recMap.erase(mit))
88  delete *mit;
89 
90  // ----------------------------------------------------------------------
91  // Build Response
92  // ----------------------------------------------------------------------
93 
94  DTC::ProgramList *pPrograms = new DTC::ProgramList();
95  int nAvailable = 0;
96 
97  int nMax = (nCount > 0) ? nCount : progList.size();
98 
99  nAvailable = 0;
100  nCount = 0;
101 
102  QRegExp rTitleRegEx = QRegExp(sTitleRegEx, Qt::CaseInsensitive);
103 
104  for( unsigned int n = 0; n < progList.size(); n++)
105  {
106  ProgramInfo *pInfo = progList[ n ];
107 
108  if (pInfo->IsDeletePending() ||
109  (!sTitleRegEx.isEmpty() && !pInfo->GetTitle().contains(rTitleRegEx)) ||
110  (!sRecGroup.isEmpty() && sRecGroup != pInfo->GetRecordingGroup()) ||
111  (!sStorageGroup.isEmpty() && sStorageGroup != pInfo->GetStorageGroup()))
112  continue;
113 
114  if ((nAvailable < nStartIndex) ||
115  (nCount >= nMax))
116  {
117  ++nAvailable;
118  continue;
119  }
120 
121  ++nAvailable;
122  ++nCount;
123 
124  DTC::Program *pProgram = pPrograms->AddNewProgram();
125 
126  FillProgramInfo( pProgram, pInfo, true );
127  }
128 
129  // ----------------------------------------------------------------------
130 
131  pPrograms->setStartIndex ( nStartIndex );
132  pPrograms->setCount ( nCount );
133  pPrograms->setTotalAvailable( nAvailable );
134  pPrograms->setAsOf ( MythDate::current() );
135  pPrograms->setVersion ( MYTH_BINARY_VERSION );
136  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
137 
138  return pPrograms;
139 }
140 
142 //
144 
146  int chanid, const QDateTime &recstarttsRaw)
147 {
148  if ((RecordedId <= 0) &&
149  (chanid <= 0 || !recstarttsRaw.isValid()))
150  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
151 
152  // TODO Should use RecordingInfo
153  ProgramInfo pi;
154  if (RecordedId > 0)
155  pi = ProgramInfo(RecordedId);
156  else
157  pi = ProgramInfo(chanid, recstarttsRaw.toUTC());
158 
159  DTC::Program *pProgram = new DTC::Program();
160  FillProgramInfo( pProgram, &pi, true );
161 
162  return pProgram;
163 }
164 
166 //
168 
169 bool Dvr::RemoveRecorded(int RecordedId,
170  int chanid, const QDateTime &recstarttsRaw,
171  bool forceDelete, bool allowRerecord)
172 {
173  return DeleteRecording(RecordedId, chanid, recstarttsRaw, forceDelete,
174  allowRerecord);
175 }
176 
177 
178 bool Dvr::DeleteRecording(int RecordedId,
179  int chanid, const QDateTime &recstarttsRaw,
180  bool forceDelete, bool allowRerecord)
181 {
182  if ((RecordedId <= 0) &&
183  (chanid <= 0 || !recstarttsRaw.isValid()))
184  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
185 
186  // TODO Should use RecordingInfo
187  ProgramInfo pi;
188  if (RecordedId > 0)
189  pi = ProgramInfo(RecordedId);
190  else
191  pi = ProgramInfo(chanid, recstarttsRaw.toUTC());
192 
193  if (pi.GetChanID() && pi.HasPathname())
194  {
195  QString cmd = QString("DELETE_RECORDING %1 %2 %3 %4")
196  .arg(pi.GetChanID())
198  .arg(forceDelete ? "FORCE" : "NO_FORCE")
199  .arg(allowRerecord ? "FORGET" : "NO_FORGET");
200  MythEvent me(cmd);
201 
202  gCoreContext->dispatch(me);
203  return true;
204  }
205 
206  return false;
207 }
208 
210 //
212 
213 bool Dvr::UnDeleteRecording(int RecordedId,
214  int chanid, const QDateTime &recstarttsRaw)
215 {
216  if ((RecordedId <= 0) &&
217  (chanid <= 0 || !recstarttsRaw.isValid()))
218  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
219 
220  RecordingInfo ri;
221  if (RecordedId > 0)
222  ri = RecordingInfo(RecordedId);
223  else
224  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
225 
226  if (ri.GetChanID() && ri.HasPathname())
227  {
228  QString cmd = QString("UNDELETE_RECORDING %1 %2")
229  .arg(ri.GetChanID())
231  MythEvent me(cmd);
232 
233  gCoreContext->dispatch(me);
234  return true;
235  }
236 
237  return false;
238 }
239 
241 //
243 
244 bool Dvr::StopRecording(int RecordedId)
245 {
246  if (RecordedId <= 0)
247  throw QString("Recorded ID is invalid.");
248 
249  RecordingInfo ri = RecordingInfo(RecordedId);
250 
251  if (ri.GetChanID())
252  {
253  QString cmd = QString("STOP_RECORDING %1 %2")
254  .arg(ri.GetChanID())
256  MythEvent me(cmd);
257 
258  gCoreContext->dispatch(me);
259  return true;
260  }
261  else
262  throw QString("RecordID %1 not found").arg(RecordedId);
263 
264  return false;
265 }
266 
268 //
270 
271 bool Dvr::ReactivateRecording(int RecordedId)
272 {
273  if (RecordedId <= 0)
274  throw QString("Recorded ID is invalid.");
275 
276  RecordingInfo ri = RecordingInfo(RecordedId);
277 
278  ri.ReactivateRecording();
279 
280  return true;
281 }
282 
284 //
286 
288 {
289  QString cmd = QString("RESCHEDULE_RECORDINGS");
290  MythEvent me(cmd);
291 
292  gCoreContext->dispatch(me);
293  return true;
294 }
295 
297 //
299 
300 bool Dvr::UpdateRecordedWatchedStatus ( int RecordedId,
301  int chanid,
302  const QDateTime &recstarttsRaw,
303  bool watched)
304 {
305  if ((RecordedId <= 0) &&
306  (chanid <= 0 || !recstarttsRaw.isValid()))
307  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
308 
309  // TODO Should use RecordingInfo
310  ProgramInfo pi;
311  if (RecordedId > 0)
312  pi = ProgramInfo(RecordedId);
313  else
314  pi = ProgramInfo(chanid, recstarttsRaw.toUTC());
315 
316  if (pi.GetChanID() && pi.HasPathname())
317  {
318  pi.SaveWatched(watched);
319  return true;
320  }
321 
322  return false;
323 }
324 
326 //
328 
329 long Dvr::GetSavedBookmark( int RecordedId,
330  int chanid,
331  const QDateTime &recstarttsRaw,
332  const QString &offsettype )
333 {
334  if ((RecordedId <= 0) &&
335  (chanid <= 0 || !recstarttsRaw.isValid()))
336  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
337 
338  RecordingInfo ri;
339  if (RecordedId > 0)
340  ri = RecordingInfo(RecordedId);
341  else
342  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
343  uint64_t offset;
344  bool isend=true;
345  uint64_t position = ri.QueryBookmark();
346  if (offsettype.toLower() == "position"){
347  ri.QueryKeyFramePosition(&offset, position, isend);
348  return offset;
349  }
350  else if (offsettype.toLower() == "duration"){
351  ri.QueryKeyFrameDuration(&offset, position, isend);
352  return offset;
353  }
354  else
355  return position;
356 }
357 
359 //
361 
362 bool Dvr::SetSavedBookmark( int RecordedId,
363  int chanid,
364  const QDateTime &recstarttsRaw,
365  const QString &offsettype,
366  long Offset )
367 {
368  if ((RecordedId <= 0) &&
369  (chanid <= 0 || !recstarttsRaw.isValid()))
370  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
371 
372  if (Offset < 0)
373  throw QString("Offset must be >= 0.");
374 
375  RecordingInfo ri;
376  if (RecordedId > 0)
377  ri = RecordingInfo(RecordedId);
378  else
379  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
380  uint64_t position;
381  bool isend=true;
382  if (offsettype.toLower() == "position"){
383  if (!ri.QueryPositionKeyFrame(&position, Offset, isend))
384  return false;
385  }
386  else if (offsettype.toLower() == "duration"){
387  if (!ri.QueryDurationKeyFrame(&position, Offset, isend))
388  return false;
389  }
390  else
391  position = Offset;
392  ri.SaveBookmark(position);
393  return true;
394 }
395 
397 //
399 
401  int chanid,
402  const QDateTime &recstarttsRaw,
403  const QString &offsettype )
404 {
405  int marktype;
406  if ((RecordedId <= 0) &&
407  (chanid <= 0 || !recstarttsRaw.isValid()))
408  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
409 
410  RecordingInfo ri;
411  if (RecordedId > 0)
412  ri = RecordingInfo(RecordedId);
413  else
414  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
415 
416  DTC::CutList* pCutList = new DTC::CutList();
417  if (offsettype == "Position")
418  marktype = 1;
419  else if (offsettype == "Duration")
420  marktype = 2;
421  else
422  marktype = 0;
423 
424  FillCutList(pCutList, &ri, marktype);
425 
426  return pCutList;
427 }
428 
430 //
432 
434  int chanid,
435  const QDateTime &recstarttsRaw,
436  const QString &offsettype )
437 {
438  int marktype;
439  if ((RecordedId <= 0) &&
440  (chanid <= 0 || !recstarttsRaw.isValid()))
441  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
442 
443  RecordingInfo ri;
444  if (RecordedId > 0)
445  ri = RecordingInfo(RecordedId);
446  else
447  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
448 
449  DTC::CutList* pCutList = new DTC::CutList();
450  if (offsettype == "Position")
451  marktype = 1;
452  else if (offsettype == "Duration")
453  marktype = 2;
454  else
455  marktype = 0;
456 
457  FillCommBreak(pCutList, &ri, marktype);
458 
459  return pCutList;
460 }
461 
463 //
465 
467  const QString &offsettype )
468 {
469  MarkTypes marktype;
470  if (RecordedId <= 0)
471  throw QString("Recorded ID appears invalid.");
472 
473  RecordingInfo ri;
474  ri = RecordingInfo(RecordedId);
475 
476  DTC::CutList* pCutList = new DTC::CutList();
477  if (offsettype == "BYTES")
478  marktype = MARK_GOP_BYFRAME;
479  else if (offsettype == "DURATION")
480  marktype = MARK_DURATION_MS;
481  else
482  {
483  delete pCutList;
484  throw QString("Type must be 'BYTES' or 'DURATION'.");
485  }
486 
487  FillSeek(pCutList, &ri, marktype);
488 
489  return pCutList;
490 }
491 
493 //
495 
497  int nCount )
498 {
499  pginfolist_t infoList;
500 
501  if (expirer)
502  expirer->GetAllExpiring( infoList );
503 
504  // ----------------------------------------------------------------------
505  // Build Response
506  // ----------------------------------------------------------------------
507 
508  DTC::ProgramList *pPrograms = new DTC::ProgramList();
509 
510  nStartIndex = (nStartIndex > 0) ? min( nStartIndex, (int)infoList.size() ) : 0;
511  nCount = (nCount > 0) ? min( nCount, (int)infoList.size() ) : infoList.size();
512  int nEndIndex = min((nStartIndex + nCount), (int)infoList.size() );
513 
514  for( int n = nStartIndex; n < nEndIndex; n++)
515  {
516  ProgramInfo *pInfo = infoList[ n ];
517 
518  if (pInfo != NULL)
519  {
520  DTC::Program *pProgram = pPrograms->AddNewProgram();
521 
522  FillProgramInfo( pProgram, pInfo, true );
523 
524  delete pInfo;
525  }
526  }
527 
528  // ----------------------------------------------------------------------
529 
530  pPrograms->setStartIndex ( nStartIndex );
531  pPrograms->setCount ( nCount );
532  pPrograms->setTotalAvailable( infoList.size() );
533  pPrograms->setAsOf ( MythDate::current() );
534  pPrograms->setVersion ( MYTH_BINARY_VERSION );
535  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
536 
537  return pPrograms;
538 }
539 
541 //
543 
545 {
546 
547  DTC::EncoderList* pList = new DTC::EncoderList();
548 
549  QList<InputInfo> inputInfoList = CardUtil::GetAllInputInfo();
550  QMap<int, EncoderLink *>::Iterator iter = tvList.begin();
551 
552  for (; iter != tvList.end(); ++iter)
553  {
554  EncoderLink *elink = *iter;
555 
556  if (elink != NULL)
557  {
558  DTC::Encoder *pEncoder = pList->AddNewEncoder();
559 
560  pEncoder->setId ( elink->GetInputID() );
561  pEncoder->setState ( elink->GetState() );
562  pEncoder->setLocal ( elink->IsLocal() );
563  pEncoder->setConnected ( elink->IsConnected() );
564  pEncoder->setSleepStatus ( elink->GetSleepStatus() );
565  // pEncoder->setLowOnFreeSpace( elink->isLowOnFreeSpace());
566 
567  if (pEncoder->Local())
568  pEncoder->setHostName( gCoreContext->GetHostName() );
569  else
570  pEncoder->setHostName( elink->GetHostName() );
571 
572  QList<InputInfo>::iterator it = inputInfoList.begin();
573  for (; it < inputInfoList.end(); ++it)
574  {
575  InputInfo inputInfo = *it;
576  if (inputInfo.inputid == static_cast<uint>(elink->GetInputID()))
577  {
578  DTC::Input *input = pEncoder->AddNewInput();
579  FillInputInfo(input, inputInfo);
580  }
581  }
582 
583  switch ( pEncoder->State() )
584  {
588  {
589  ProgramInfo *pInfo = elink->GetRecording();
590 
591  if (pInfo)
592  {
593  DTC::Program *pProgram = pEncoder->Recording();
594 
595  FillProgramInfo( pProgram, pInfo, true, true );
596 
597  delete pInfo;
598  }
599 
600  break;
601  }
602 
603  default:
604  break;
605  }
606  }
607  }
608  return pList;
609 }
610 
612 //
614 
616 {
617  DTC::InputList *pList = new DTC::InputList();
618 
619  QList<InputInfo> inputInfoList = CardUtil::GetAllInputInfo();
620  QList<InputInfo>::iterator it = inputInfoList.begin();
621  for (; it < inputInfoList.end(); ++it)
622  {
623  InputInfo inputInfo = *it;
624  DTC::Input *input = pList->AddNewInput();
625  FillInputInfo(input, inputInfo);
626  }
627 
628  return pList;
629 }
630 
632 //
634 
635 QStringList Dvr::GetRecGroupList()
636 {
637  MSqlQuery query(MSqlQuery::InitCon());
638  query.prepare("SELECT recgroup FROM recgroups WHERE recgroup <> 'Deleted' "
639  "ORDER BY recgroup");
640 
641  QStringList result;
642  if (!query.exec())
643  {
644  MythDB::DBError("GetRecGroupList", query);
645  return result;
646  }
647 
648  while (query.next())
649  result << query.value(0).toString();
650 
651  return result;
652 }
653 
655 //
657 
659 {
661 }
662 
664 //
666 
668 {
669  return PlayGroup::GetNames();
670 }
671 
673 //
675 
677 {
679 
680  MSqlQuery query(MSqlQuery::InitCon());
681 
682  query.prepare("SELECT filterid, description, newruledefault "
683  "FROM recordfilter ORDER BY filterid");
684 
685  if (query.exec())
686  {
687  while (query.next())
688  {
689  DTC::RecRuleFilter* ruleFilter = filterList->AddNewRecRuleFilter();
690  ruleFilter->setId(query.value(0).toInt());
691  ruleFilter->setDescription(QObject::tr(query.value(1).toString()
692  .toUtf8().constData()));
693  }
694  }
695 
696  return filterList;
697 }
698 
700 //
702 
703 QStringList Dvr::GetTitleList(const QString& RecGroup)
704 {
705  MSqlQuery query(MSqlQuery::InitCon());
706 
707  QString querystr = "SELECT DISTINCT title FROM recorded "
708  "WHERE deletepending = 0";
709 
710  if (!RecGroup.isEmpty())
711  querystr += " AND recgroup = :RECGROUP";
712  else
713  querystr += " AND recgroup != 'Deleted'";
714 
715  querystr += " ORDER BY title";
716 
717  query.prepare(querystr);
718 
719  if (!RecGroup.isEmpty())
720  query.bindValue(":RECGROUP", RecGroup);
721 
722  QStringList result;
723  if (!query.exec())
724  {
725  MythDB::DBError("GetTitleList recorded", query);
726  return result;
727  }
728 
729  while (query.next())
730  result << query.value(0).toString();
731 
732  return result;
733 }
734 
736 //
738 
740 {
741  MSqlQuery query(MSqlQuery::InitCon());
742 
743  QString querystr = QString(
744  "SELECT title, inetref, count(title) as count "
745  " FROM recorded AS r "
746  " JOIN recgroups AS g ON r.recgroupid = g.recgroupid "
747  " WHERE g.recgroup != 'LiveTV' "
748  " AND r.deletepending = 0 "
749  " GROUP BY title, inetref "
750  " ORDER BY title");
751 
752  query.prepare(querystr);
753 
754  DTC::TitleInfoList *pTitleInfos = new DTC::TitleInfoList();
755  if (!query.exec())
756  {
757  MythDB::DBError("GetTitleList recorded", query);
758  return pTitleInfos;
759  }
760 
761  while (query.next())
762  {
763  DTC::TitleInfo *pTitleInfo = pTitleInfos->AddNewTitleInfo();
764 
765  pTitleInfo->setTitle(query.value(0).toString());
766  pTitleInfo->setInetref(query.value(1).toString());
767  pTitleInfo->setCount(query.value(2).toInt());
768  }
769 
770  return pTitleInfos;
771 }
772 
774 //
776 
778  int nCount,
779  bool bShowAll,
780  int nRecordId,
781  int nRecStatus )
782 {
783  RecordingList recordingList; // Auto-delete deque
784  RecList tmpList; // Standard deque, objects must be deleted
785 
786  if (nRecordId <= 0)
787  nRecordId = -1;
788 
789  // NOTE: Fetching this information directly from the schedule is
790  // significantly faster than using ProgramInfo::LoadFromScheduler()
791  Scheduler *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler());
792  if (scheduler)
793  scheduler->GetAllPending(tmpList, nRecordId);
794 
795  // Sort the upcoming into only those which will record
796  RecList::iterator it = tmpList.begin();
797  for(; it < tmpList.end(); ++it)
798  {
799  if ((nRecStatus != 0) &&
800  ((*it)->GetRecordingStatus() != nRecStatus))
801  {
802  delete *it;
803  *it = NULL;
804  continue;
805  }
806 
807  if (!bShowAll && ((((*it)->GetRecordingStatus() >= RecStatus::Pending) &&
808  ((*it)->GetRecordingStatus() <= RecStatus::WillRecord)) ||
809  ((*it)->GetRecordingStatus() == RecStatus::Conflict)) &&
810  ((*it)->GetRecordingEndTime() > MythDate::current()))
811  {
812  recordingList.push_back(new RecordingInfo(**it));
813  }
814  else if (bShowAll &&
815  ((*it)->GetRecordingEndTime() > MythDate::current()))
816  {
817  recordingList.push_back(new RecordingInfo(**it));
818  }
819 
820  delete *it;
821  *it = NULL;
822  }
823 
824  // ----------------------------------------------------------------------
825  // Build Response
826  // ----------------------------------------------------------------------
827 
828  DTC::ProgramList *pPrograms = new DTC::ProgramList();
829 
830  nStartIndex = (nStartIndex > 0) ? min( nStartIndex, (int)recordingList.size() ) : 0;
831  nCount = (nCount > 0) ? min( nCount, (int)recordingList.size() ) : recordingList.size();
832  int nEndIndex = min((nStartIndex + nCount), (int)recordingList.size() );
833 
834  for( int n = nStartIndex; n < nEndIndex; n++)
835  {
836  ProgramInfo *pInfo = recordingList[ n ];
837 
838  DTC::Program *pProgram = pPrograms->AddNewProgram();
839 
840  FillProgramInfo( pProgram, pInfo, true );
841  }
842 
843  // ----------------------------------------------------------------------
844 
845  pPrograms->setStartIndex ( nStartIndex );
846  pPrograms->setCount ( nCount );
847  pPrograms->setTotalAvailable( recordingList.size() );
848  pPrograms->setAsOf ( MythDate::current() );
849  pPrograms->setVersion ( MYTH_BINARY_VERSION );
850  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
851 
852  return pPrograms;
853 }
854 
856 //
858 
860  int nCount,
861  int nRecordId )
862 {
863  RecordingList recordingList; // Auto-delete deque
864  RecList tmpList; // Standard deque, objects must be deleted
865 
866  if (nRecordId <= 0)
867  nRecordId = -1;
868 
869  // NOTE: Fetching this information directly from the schedule is
870  // significantly faster than using ProgramInfo::LoadFromScheduler()
871  Scheduler *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler());
872  if (scheduler)
873  scheduler->GetAllPending(tmpList, nRecordId);
874 
875  // Sort the upcoming into only those which are conflicts
876  RecList::iterator it = tmpList.begin();
877  for(; it < tmpList.end(); ++it)
878  {
879  if (((*it)->GetRecordingStatus() == RecStatus::Conflict) &&
880  ((*it)->GetRecordingStartTime() >= MythDate::current()))
881  {
882  recordingList.push_back(new RecordingInfo(**it));
883  }
884  delete *it;
885  *it = NULL;
886  }
887 
888  // ----------------------------------------------------------------------
889  // Build Response
890  // ----------------------------------------------------------------------
891 
892  DTC::ProgramList *pPrograms = new DTC::ProgramList();
893 
894  nStartIndex = (nStartIndex > 0) ? min( nStartIndex, (int)recordingList.size() ) : 0;
895  nCount = (nCount > 0) ? min( nCount, (int)recordingList.size() ) : recordingList.size();
896  int nEndIndex = min((nStartIndex + nCount), (int)recordingList.size() );
897 
898  for( int n = nStartIndex; n < nEndIndex; n++)
899  {
900  ProgramInfo *pInfo = recordingList[ n ];
901 
902  DTC::Program *pProgram = pPrograms->AddNewProgram();
903 
904  FillProgramInfo( pProgram, pInfo, true );
905  }
906 
907  // ----------------------------------------------------------------------
908 
909  pPrograms->setStartIndex ( nStartIndex );
910  pPrograms->setCount ( nCount );
911  pPrograms->setTotalAvailable( recordingList.size() );
912  pPrograms->setAsOf ( MythDate::current() );
913  pPrograms->setVersion ( MYTH_BINARY_VERSION );
914  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
915 
916  return pPrograms;
917 }
918 
920  QString sTitle,
921  QString sSubtitle,
922  QString sDescription,
923  QString sCategory,
924  QDateTime recstarttsRaw,
925  QDateTime recendtsRaw,
926  QString sSeriesId,
927  QString sProgramId,
928  int nChanId,
929  QString sStation,
930  int nFindDay,
931  QTime tFindTime,
932  int nParentId,
933  bool bInactive,
934  uint nSeason,
935  uint nEpisode,
936  QString sInetref,
937  QString sType,
938  QString sSearchType,
939  int nRecPriority,
940  uint nPreferredInput,
941  int nStartOffset,
942  int nEndOffset,
943  QString sDupMethod,
944  QString sDupIn,
945  uint nFilter,
946  QString sRecProfile,
947  QString sRecGroup,
948  QString sStorageGroup,
949  QString sPlayGroup,
950  bool bAutoExpire,
951  int nMaxEpisodes,
952  bool bMaxNewest,
953  bool bAutoCommflag,
954  bool bAutoTranscode,
955  bool bAutoMetaLookup,
956  bool bAutoUserJob1,
957  bool bAutoUserJob2,
958  bool bAutoUserJob3,
959  bool bAutoUserJob4,
960  int nTranscoder)
961 {
962  QDateTime recstartts = recstarttsRaw.toUTC();
963  QDateTime recendts = recendtsRaw.toUTC();
964  RecordingRule rule;
965  rule.LoadTemplate("Default");
966 
967  if (sType.isEmpty())
968  sType = "single";
969 
970  if (sSearchType.isEmpty())
971  sSearchType = "none";
972 
973  if (sDupMethod.isEmpty())
974  sDupMethod = "subtitleanddescription";
975 
976  if (sDupIn.isEmpty())
977  sDupIn = "all";
978 
979  rule.m_title = sTitle;
980  rule.m_subtitle = sSubtitle;
981  rule.m_description = sDescription;
982 
983  rule.m_startdate = recstartts.date();
984  rule.m_starttime = recstartts.time();
985  rule.m_enddate = recendts.date();
986  rule.m_endtime = recendts.time();
987 
988  rule.m_type = recTypeFromString(sType);
989  rule.m_searchType = searchTypeFromString(sSearchType);
990  rule.m_dupMethod = dupMethodFromString(sDupMethod);
991  rule.m_dupIn = dupInFromString(sDupIn);
992 
993  if (sRecProfile.isEmpty())
994  sRecProfile = "Default";
995 
996  if (sRecGroup.isEmpty())
997  sRecGroup = "Default";
998 
999  if (sStorageGroup.isEmpty())
1000  sStorageGroup = "Default";
1001 
1002  if (sPlayGroup.isEmpty())
1003  sPlayGroup = "Default";
1004 
1005  rule.m_category = sCategory;
1006  rule.m_seriesid = sSeriesId;
1007  rule.m_programid = sProgramId;
1008 
1009  rule.m_channelid = nChanId;
1010  rule.m_station = sStation;
1011 
1012  rule.m_findday = nFindDay;
1013  rule.m_findtime = tFindTime;
1014 
1015  rule.m_recProfile = sRecProfile;
1016  rule.m_recGroupID = RecordingInfo::GetRecgroupID(sRecGroup);
1017  if (rule.m_recGroupID == 0)
1019  rule.m_storageGroup = sStorageGroup;
1020  rule.m_playGroup = sPlayGroup;
1021 
1022  rule.m_parentRecID = nParentId;
1023  rule.m_isInactive = bInactive;
1024 
1025  rule.m_season = nSeason;
1026  rule.m_episode = nEpisode;
1027  rule.m_inetref = sInetref;
1028 
1029  rule.m_recPriority = nRecPriority;
1030  rule.m_prefInput = nPreferredInput;
1031  rule.m_startOffset = nStartOffset;
1032  rule.m_endOffset = nEndOffset;
1033  rule.m_filter = nFilter;
1034 
1035  rule.m_autoExpire = bAutoExpire;
1036  rule.m_maxEpisodes = nMaxEpisodes;
1037  rule.m_maxNewest = bMaxNewest;
1038 
1039  rule.m_autoCommFlag = bAutoCommflag;
1040  rule.m_autoTranscode = bAutoTranscode;
1041  rule.m_autoMetadataLookup = bAutoMetaLookup;
1042 
1043  rule.m_autoUserJob1 = bAutoUserJob1;
1044  rule.m_autoUserJob2 = bAutoUserJob2;
1045  rule.m_autoUserJob3 = bAutoUserJob3;
1046  rule.m_autoUserJob4 = bAutoUserJob4;
1047 
1048  rule.m_transcoder = nTranscoder;
1049 
1050  QString msg;
1051  if (!rule.IsValid(msg))
1052  throw msg;
1053 
1054  rule.Save();
1055 
1056  uint recid = rule.m_recordID;
1057 
1058  return recid;
1059 }
1060 
1062  QString sTitle,
1063  QString sSubtitle,
1064  QString sDescription,
1065  QString sCategory,
1066  QDateTime dStartTimeRaw,
1067  QDateTime dEndTimeRaw,
1068  QString sSeriesId,
1069  QString sProgramId,
1070  int nChanId,
1071  QString sStation,
1072  int nFindDay,
1073  QTime tFindTime,
1074  bool bInactive,
1075  uint nSeason,
1076  uint nEpisode,
1077  QString sInetref,
1078  QString sType,
1079  QString sSearchType,
1080  int nRecPriority,
1081  uint nPreferredInput,
1082  int nStartOffset,
1083  int nEndOffset,
1084  QString sDupMethod,
1085  QString sDupIn,
1086  uint nFilter,
1087  QString sRecProfile,
1088  QString sRecGroup,
1089  QString sStorageGroup,
1090  QString sPlayGroup,
1091  bool bAutoExpire,
1092  int nMaxEpisodes,
1093  bool bMaxNewest,
1094  bool bAutoCommflag,
1095  bool bAutoTranscode,
1096  bool bAutoMetaLookup,
1097  bool bAutoUserJob1,
1098  bool bAutoUserJob2,
1099  bool bAutoUserJob3,
1100  bool bAutoUserJob4,
1101  int nTranscoder)
1102 {
1103  if (nRecordId <= 0 )
1104  throw QString("Record ID is invalid.");
1105 
1106  RecordingRule pRule;
1107  pRule.m_recordID = nRecordId;
1108  pRule.Load();
1109 
1110  if (!pRule.IsLoaded())
1111  throw QString("Record ID does not exist.");
1112 
1113  QDateTime recstartts = dStartTimeRaw.toUTC();
1114  QDateTime recendts = dEndTimeRaw.toUTC();
1115 
1116  pRule.m_isInactive = bInactive;
1117  if (sType.isEmpty())
1118  sType = "single";
1119 
1120  if (sSearchType.isEmpty())
1121  sSearchType = "none";
1122 
1123  if (sDupMethod.isEmpty())
1124  sDupMethod = "subtitleanddescription";
1125 
1126  if (sDupIn.isEmpty())
1127  sDupIn = "all";
1128 
1129  pRule.m_type = recTypeFromString(sType);
1130  pRule.m_searchType = searchTypeFromString(sSearchType);
1131  pRule.m_dupMethod = dupMethodFromString(sDupMethod);
1132  pRule.m_dupIn = dupInFromString(sDupIn);
1133 
1134  if (sRecProfile.isEmpty())
1135  sRecProfile = "Default";
1136 
1137  if (sRecGroup.isEmpty())
1138  sRecGroup = "Default";
1139 
1140  if (sStorageGroup.isEmpty())
1141  sStorageGroup = "Default";
1142 
1143  if (sPlayGroup.isEmpty())
1144  sPlayGroup = "Default";
1145 
1146  if (!sTitle.isEmpty())
1147  pRule.m_title = sTitle;
1148 
1149  if (!sSubtitle.isEmpty())
1150  pRule.m_subtitle = sSubtitle;
1151 
1152  if(!sDescription.isEmpty())
1153  pRule.m_description = sDescription;
1154 
1155  if (!sCategory.isEmpty())
1156  pRule.m_category = sCategory;
1157 
1158  if (!sSeriesId.isEmpty())
1159  pRule.m_seriesid = sSeriesId;
1160 
1161  if (!sProgramId.isEmpty())
1162  pRule.m_programid = sProgramId;
1163 
1164  if (nChanId)
1165  pRule.m_channelid = nChanId;
1166  if (!sStation.isEmpty())
1167  pRule.m_station = sStation;
1168 
1169  pRule.m_startdate = recstartts.date();
1170  pRule.m_starttime = recstartts.time();
1171  pRule.m_enddate = recendts.date();
1172  pRule.m_endtime = recendts.time();
1173 
1174  pRule.m_findday = nFindDay;
1175  pRule.m_findtime = tFindTime;
1176 
1177  pRule.m_recProfile = sRecProfile;
1178  pRule.m_recGroupID = RecordingInfo::GetRecgroupID(sRecGroup);
1179  if (pRule.m_recGroupID == 0)
1181  pRule.m_storageGroup = sStorageGroup;
1182  pRule.m_playGroup = sPlayGroup;
1183 
1184  pRule.m_isInactive = bInactive;
1185 
1186  pRule.m_season = nSeason;
1187  pRule.m_episode = nEpisode;
1188  pRule.m_inetref = sInetref;
1189 
1190  pRule.m_recPriority = nRecPriority;
1191  pRule.m_prefInput = nPreferredInput;
1192  pRule.m_startOffset = nStartOffset;
1193  pRule.m_endOffset = nEndOffset;
1194  pRule.m_filter = nFilter;
1195 
1196  pRule.m_autoExpire = bAutoExpire;
1197  pRule.m_maxEpisodes = nMaxEpisodes;
1198  pRule.m_maxNewest = bMaxNewest;
1199 
1200  pRule.m_autoCommFlag = bAutoCommflag;
1201  pRule.m_autoTranscode = bAutoTranscode;
1202  pRule.m_autoMetadataLookup = bAutoMetaLookup;
1203 
1204  pRule.m_autoUserJob1 = bAutoUserJob1;
1205  pRule.m_autoUserJob2 = bAutoUserJob2;
1206  pRule.m_autoUserJob3 = bAutoUserJob3;
1207  pRule.m_autoUserJob4 = bAutoUserJob4;
1208 
1209  pRule.m_transcoder = nTranscoder;
1210 
1211  QString msg;
1212  if (!pRule.IsValid(msg))
1213  throw msg;
1214 
1215  bool bResult = pRule.Save();
1216 
1217  return bResult;
1218 }
1219 
1221 {
1222  bool bResult = false;
1223 
1224  if (nRecordId <= 0 )
1225  throw QString("Record ID does not exist.");
1226 
1227  RecordingRule pRule;
1228  pRule.m_recordID = nRecordId;
1229 
1230  bResult = pRule.Delete();
1231 
1232  return bResult;
1233 }
1234 
1235 bool Dvr::AddDontRecordSchedule(int nChanId, const QDateTime &dStartTime,
1236  bool bNeverRecord)
1237 {
1238  bool bResult = true;
1239 
1240  if (nChanId <= 0 || !dStartTime.isValid())
1241  throw QString("Program does not exist.");
1242 
1243  ProgramInfo *pi = LoadProgramFromProgram(nChanId, dStartTime.toUTC());
1244 
1245  if (!pi)
1246  throw QString("Program does not exist.");
1247 
1248  // Why RecordingInfo instead of ProgramInfo? Good question ...
1249  RecordingInfo recInfo = RecordingInfo(*pi);
1250 
1251  delete pi;
1252 
1253  if (bNeverRecord)
1254  {
1255  recInfo.ApplyNeverRecord();
1256  }
1257  else
1259 
1260  return bResult;
1261 }
1262 
1264  int nCount,
1265  const QString &Sort,
1266  bool Descending )
1267 {
1268  Scheduler::SchedSortColumn sortingColumn;
1269  if (Sort.toLower() == "lastrecorded")
1270  sortingColumn = Scheduler::kSortLastRecorded;
1271  else if (Sort.toLower() == "nextrecording")
1272  sortingColumn = Scheduler::kSortNextRecording;
1273  else if (Sort.toLower() == "title")
1274  sortingColumn = Scheduler::kSortTitle;
1275  else if (Sort.toLower() == "priority")
1276  sortingColumn = Scheduler::kSortPriority;
1277  else if (Sort.toLower() == "type")
1278  sortingColumn = Scheduler::kSortType;
1279  else
1280  sortingColumn = Scheduler::kSortTitle;
1281 
1282  RecList recList;
1283  Scheduler::GetAllScheduled(recList, sortingColumn, !Descending);
1284 
1285  // ----------------------------------------------------------------------
1286  // Build Response
1287  // ----------------------------------------------------------------------
1288 
1289  DTC::RecRuleList *pRecRules = new DTC::RecRuleList();
1290 
1291  nStartIndex = (nStartIndex > 0) ? min( nStartIndex, (int)recList.size() ) : 0;
1292  nCount = (nCount > 0) ? min( nCount, (int)recList.size() ) : recList.size();
1293  int nEndIndex = min((nStartIndex + nCount), (int)recList.size() );
1294 
1295  for( int n = nStartIndex; n < nEndIndex; n++)
1296  {
1297  RecordingInfo *info = recList[n];
1298 
1299  if (info != NULL)
1300  {
1301  DTC::RecRule *pRecRule = pRecRules->AddNewRecRule();
1302 
1303  FillRecRuleInfo( pRecRule, info->GetRecordingRule() );
1304  }
1305  }
1306 
1307  // ----------------------------------------------------------------------
1308 
1309  pRecRules->setStartIndex ( nStartIndex );
1310  pRecRules->setCount ( nCount );
1311  pRecRules->setTotalAvailable( recList.size() );
1312  pRecRules->setAsOf ( MythDate::current() );
1313  pRecRules->setVersion ( MYTH_BINARY_VERSION );
1314  pRecRules->setProtoVer ( MYTH_PROTO_VERSION );
1315 
1316  while (!recList.empty())
1317  {
1318  delete recList.back();
1319  recList.pop_back();
1320  }
1321 
1322  return pRecRules;
1323 }
1324 
1326  QString sTemplate,
1327  int nRecordedId,
1328  int nChanId,
1329  QDateTime dStartTimeRaw,
1330  bool bMakeOverride )
1331 {
1332  RecordingRule rule;
1333  QDateTime dStartTime = dStartTimeRaw.toUTC();
1334 
1335  if (nRecordId > 0)
1336  {
1337  rule.m_recordID = nRecordId;
1338  if (!rule.Load())
1339  throw QString("Record ID does not exist.");
1340  }
1341  else if (!sTemplate.isEmpty())
1342  {
1343  if (!rule.LoadTemplate(sTemplate))
1344  throw QString("Template does not exist.");
1345  }
1346  else if (nRecordedId > 0) // Loads from the Recorded/Recorded Program Table
1347  {
1348  // Despite the use of ProgramInfo, this only applies to Recordings.
1349  ProgramInfo recInfo(nRecordedId);
1350  if (!rule.LoadByProgram(&recInfo))
1351  throw QString("Recording does not exist");
1352  }
1353  else if (nChanId > 0 && dStartTime.isValid()) // Loads from Program Table, should NOT be used with recordings
1354  {
1355  // Despite the use of RecordingInfo, this only applies to programs in the
1356  // present or future, not to recordings? Confused yet?
1358  RecordingInfo info(nChanId, dStartTime, false, 0, &status);
1359  if (status != RecordingInfo::kFoundProgram)
1360  throw QString("Program does not exist.");
1361  RecordingRule *pRule = info.GetRecordingRule();
1362  if (bMakeOverride && rule.m_type != kSingleRecord &&
1363  rule.m_type != kOverrideRecord && rule.m_type != kDontRecord)
1364  pRule->MakeOverride();
1365  rule = *pRule;
1366  }
1367  else
1368  {
1369  throw QString("Invalid request.");
1370  }
1371 
1372  DTC::RecRule *pRecRule = new DTC::RecRule();
1373  FillRecRuleInfo( pRecRule, &rule );
1374 
1375  return pRecRule;
1376 }
1377 
1379 {
1380  bool bResult = false;
1381 
1382  if (nRecordId <= 0 )
1383  throw QString("Record ID appears invalid.");
1384 
1385  RecordingRule pRule;
1386  pRule.m_recordID = nRecordId;
1387  pRule.Load();
1388 
1389  if (pRule.IsLoaded())
1390  {
1391  pRule.m_isInactive = false;
1392  bResult = pRule.Save();
1393  }
1394 
1395  return bResult;
1396 }
1397 
1399 {
1400  bool bResult = false;
1401 
1402  if (nRecordId <= 0 )
1403  throw QString("Record ID appears invalid.");
1404 
1405  RecordingRule pRule;
1406  pRule.m_recordID = nRecordId;
1407  pRule.Load();
1408 
1409  if (pRule.IsLoaded())
1410  {
1411  pRule.m_isInactive = true;
1412  bResult = pRule.Save();
1413  }
1414 
1415  return bResult;
1416 }
1417 
1418 int Dvr::RecordedIdForPathname(const QString & pathname)
1419 {
1420  uint recordedid;
1421 
1422  if (!ProgramInfo::QueryRecordedIdFromPathname(pathname, recordedid))
1423  return -1;
1424 
1425  return recordedid;
1426 }
1427 
1429 {
1430  RecStatus::Type type = static_cast<RecStatus::Type>(RecStatus);
1431  return RecStatus::toString(type);
1432 }
1433 
1434 QString Dvr::RecStatusToDescription(int RecStatus, int recType,
1435  const QDateTime &StartTime)
1436 {
1437  //if (!StartTime.isValid())
1438  // throw QString("StartTime appears invalid.");
1439  RecStatus::Type rsType = static_cast<RecStatus::Type>(RecStatus);
1440  RecordingType recordingType = static_cast<RecordingType>(recType);
1441  return RecStatus::toDescription(rsType, recordingType, StartTime);
1442 }
1443 
1444 QString Dvr::RecTypeToString(QString recType)
1445 {
1446  bool ok;
1447  RecordingType enumType = static_cast<RecordingType>(recType.toInt(&ok, 10));
1448  if (ok)
1449  return toString(enumType);
1450  // RecordingType type = static_cast<RecordingType>(recType);
1451  return toString(recTypeFromString(recType));
1452 }
1453 
1454 QString Dvr::RecTypeToDescription(QString recType)
1455 {
1456  bool ok;
1457  RecordingType enumType = static_cast<RecordingType>(recType.toInt(&ok, 10));
1458  if (ok)
1459  return toDescription(enumType);
1460  // RecordingType type = static_cast<RecordingType>(recType);
1461  return toDescription(recTypeFromString(recType));
1462 }
1463 
1464 QString Dvr::DupInToString(QString DupIn)
1465 {
1466  // RecordingDupInType type= static_cast<RecordingDupInType>(DupIn);
1467  // return toString(type);
1468  return toString(dupInFromString(DupIn));
1469 }
1470 
1471 QString Dvr::DupInToDescription(QString DupIn)
1472 {
1473  // RecordingDupInType type= static_cast<RecordingDupInType>(DupIn);
1474  //return toDescription(type);
1475  return toDescription(dupInFromString(DupIn));
1476 }
1477 
1478 QString Dvr::DupMethodToString(QString DupMethod)
1479 {
1480  // RecordingDupMethodType method = static_cast<RecordingDupMethodType>(DupMethod);
1481  return toString(dupMethodFromString(DupMethod));
1482 }
1483 
1484 QString Dvr::DupMethodToDescription(QString DupMethod)
1485 {
1486  // RecordingDupMethodType method = static_cast<RecordingDupMethodType>(DupMethod);
1487  return toDescription(dupMethodFromString(DupMethod));
1488 }
QString RecStatusToString(int RecStatus)
Definition: dvr.cpp:1428
QString m_subtitle
Definition: recordingrule.h:76
bool DeleteRecording(int RecordedId, int ChanId, const QDateTime &StartTime, bool ForceDelete, bool AllowRerecord)
Definition: dvr.cpp:178
QTime m_findtime
Day of the week for once per week etc.
Definition: recordingrule.h:95
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:785
MythScheduler * GetScheduler(void)
DTC::ProgramList * GetConflictList(int StartIndex, int Count, int RecordId)
Definition: dvr.cpp:859
Program * AddNewProgram()
Definition: programList.h:86
void bindValue(const QString &placeholder, const QVariant &val)
Definition: mythdbcon.cpp:884
AutoExpire * expirer
void ReactivateRecording(void)
Asks the scheduler to restart this recording if possible.
QString m_programid
Definition: recordingrule.h:88
DTC::RecRuleFilterList * GetRecRuleFilterList()
Definition: dvr.cpp:676
DTC::TitleInfoList * GetTitleInfoList()
Definition: dvr.cpp:739
SchedSortColumn
Definition: scheduler.h:90
ProgramInfo * LoadProgramFromProgram(const uint chanid, const QDateTime &starttime)
bool StopRecording(int RecordedId)
Definition: dvr.cpp:244
Watching LiveTV is the state for when we are watching a recording and the user has control over the c...
Definition: tv.h:63
void push_back(T info)
bool UpdateRecordedWatchedStatus(int RecordedId, int ChanId, const QDateTime &StartTime, bool Watched)
Definition: dvr.cpp:300
QString toDescription(RecordingType rectype)
Converts "rectype" into a human readable description.
bool LoadByProgram(const ProgramInfo *proginfo)
void FillProgramInfo(DTC::Program *pProgram, ProgramInfo *pInfo, bool bIncChannel, bool bDetails, bool bIncCast)
Definition: serviceUtil.cpp:44
bool Delete(bool sendSig=true)
RecSearchType searchTypeFromString(QString type)
QStringList GetPlayGroupList()
Definition: dvr.cpp:667
DTC::CutList * GetRecordedCutList(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType)
Definition: dvr.cpp:400
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
void FillRecRuleInfo(DTC::RecRule *pRecRule, RecordingRule *pRule)
RecordingRule * GetRecordingRule(void)
Returns the "record" field, creating it if necessary.
TitleInfo * AddNewTitleInfo()
Definition: titleInfoList.h:57
QString GetTitle(void) const
Definition: programinfo.h:342
RecordingType recTypeFromString(QString type)
static QString toDescription(Type, RecordingType, const QDateTime &recstartts)
Converts "recstatus" into a long human readable description.
Definition: recStatus.cpp:189
QString m_storageGroup
static QStringList getRecordingsGroups(void)
QString m_station
Definition: recordingrule.h:93
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:34
QString DupMethodToDescription(QString DupMethod)
Definition: dvr.cpp:1484
Watching Recording is the state for when we are watching an in progress recording, but the user does not have control over the channel and recorder to use.
Definition: tv.h:80
unsigned int uint
Definition: compat.h:136
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QString DupInToString(QString DupIn)
Definition: dvr.cpp:1464
AutoDeleteDeque< ProgramInfo * > ProgramList
Definition: programinfo.h:29
size_t size(void) const
DTC::CutList * GetRecordedCommBreak(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType)
Definition: dvr.cpp:433
RecordingType m_type
Definition: recordingrule.h:99
RecordingDupMethodType m_dupMethod
DTC::RecRuleList * GetRecordScheduleList(int StartIndex, int Count, const QString &Sort, bool Descending)
Definition: dvr.cpp:1263
int RecordedIdForPathname(const QString &Filename)
Definition: dvr.cpp:1418
bool RescheduleRecordings(void)
Definition: dvr.cpp:287
DTC::ProgramList * GetExpiringList(int StartIndex, int Count)
Definition: dvr.cpp:496
bool SetSavedBookmark(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType, long Offset)
Definition: dvr.cpp:362
static uint GetRecgroupID(const QString &recGroup)
Temporary helper during transition from string to ID.
__u32 type
Definition: videodev2.h:1038
QString GetStorageGroup(void) const
Definition: programinfo.h:401
QVariant value(int i) const
Definition: mythdbcon.h:182
QStringList GetRecStorageGroupList()
Definition: dvr.cpp:658
bool Save(bool sendSig=true)
MarkTypes
Definition: programtypes.h:50
RecordingDupMethodType dupMethodFromString(QString type)
Holds information on recordings and videos.
Definition: programinfo.h:66
void ApplyRecordStateChange(RecordingType newstate, bool save=true)
Sets RecordingType of "record", creating "record" if it does not exist.
bool RemoveRecorded(int RecordedId, int ChanId, const QDateTime &StartTime, bool ForceDelete, bool AllowRerecord)
Definition: dvr.cpp:169
voidpf uLong offset
Definition: ioapi.h:142
Recording Only is a TVRec only state for when we are recording a program, but there is no one current...
Definition: tv.h:84
This class is used as a container for messages.
Definition: mythevent.h:15
RecRuleFilter * AddNewRecRuleFilter()
static QString toString(Type, uint id)
static void GetAllScheduled(QStringList &strList, SchedSortColumn sortBy=kSortTitle, bool ascending=true)
Returns all scheduled programs serialized into a QStringList.
Definition: scheduler.cpp:1862
static QMap< QString, uint32_t > QueryInUseMap(void)
DTC::CutList * GetRecordedSeek(int RecordedId, const QString &OffsetType)
Definition: dvr.cpp:466
bool m_autoMetadataLookup
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
int m_findday
callsign?
Definition: recordingrule.h:94
QMap< int, EncoderLink * > tvList
QString m_playGroup
void FillCutList(DTC::CutList *pCutList, RecordingInfo *rInfo, int marktype)
QString DupMethodToString(QString DupMethod)
Definition: dvr.cpp:1478
long GetSavedBookmark(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType)
Definition: dvr.cpp:329
Input * AddNewInput()
Definition: inputList.h:59
bool ReactivateRecording(int RecordedId)
Definition: dvr.cpp:271
QString GetRecordingGroup(void) const
Definition: programinfo.h:398
QString m_description
Definition: recordingrule.h:77
void SaveBookmark(uint64_t frame)
TODO Move to RecordingInfo.
QString RecStatusToDescription(int RecStatus, int RecType, const QDateTime &StartTime)
Definition: dvr.cpp:1434
QString RecTypeToString(QString RecType)
Definition: dvr.cpp:1444
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:542
bool IsDeletePending(void) const
Definition: programinfo.h:464
Internal representation of a recording rule, mirrors the record table.
Definition: recordingrule.h:31
static QList< InputInfo > GetAllInputInfo()
Definition: cardutil.cpp:1014
bool QueryDurationKeyFrame(uint64_t *, uint64_t duration, bool backwards) const
uint64_t QueryBookmark(void) const
Gets any bookmark position in database, unless the ignore bookmark flag is set.
void GetAllExpiring(QStringList &strList)
Gets the full list of programs that can expire in expiration order.
Definition: autoexpire.cpp:837
uint inputid
unique key in DB for this input
Definition: inputinfo.h:72
QString m_seriesid
Definition: recordingrule.h:87
int m_parentRecID
Unique Recording Rule ID.
Definition: recordingrule.h:70
RecordingDupInType m_dupIn
QString RecTypeToDescription(QString RecType)
Definition: dvr.cpp:1454
void dispatch(const MythEvent &event)
QString m_inetref
Definition: recordingrule.h:89
bool QueryKeyFramePosition(uint64_t *, uint64_t keyframe, bool backwards) const
void FillSeek(DTC::CutList *pCutList, RecordingInfo *rInfo, MarkTypes marktype)
static bool QueryRecordedIdFromPathname(const QString &pathname, uint &recordedid)
bool AddDontRecordSchedule(int ChanId, const QDateTime &StartTime, bool NeverRecord)
Definition: dvr.cpp:1235
Encoder * AddNewEncoder()
Definition: encoderList.h:59
DTC::ProgramList * GetUpcomingList(int StartIndex, int Count, bool ShowAll, int RecordId, int RecStatus)
Definition: dvr.cpp:777
void FillCommBreak(DTC::CutList *pCutList, RecordingInfo *rInfo, int marktype)
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:810
RecRule * AddNewRecRule()
Definition: recRuleList.h:72
bool IsLoaded() const
Definition: recordingrule.h:55
DTC::RecRule * GetRecordSchedule(uint RecordId, QString Template, int nRecordedId, int ChanId, QDateTime StartTime, bool MakeOverride)
Definition: dvr.cpp:1325
bool UnDeleteRecording(int RecordedId, int ChanId, const QDateTime &StartTime)
Definition: dvr.cpp:213
QString m_title
Recording rule is enabled?
Definition: recordingrule.h:75
static const char * toString(OMX_AUDIO_DDPBITSTREAMID id)
Used to expire recordings to make space for new recordings.
Definition: autoexpire.h:62
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:351
void ApplyNeverRecord(void)
Set this program to never be recorded by inserting &#39;history&#39; for it into the database with a status o...
QString DupInToDescription(QString DupIn)
Definition: dvr.cpp:1471
DTC::Program * GetRecorded(int RecordedId, int ChanId, const QDateTime &StartTime)
Definition: dvr.cpp:145
static QMap< QString, bool > QueryJobsRunning(int type)
QString m_recProfile
void SaveWatched(bool watchedFlag)
Set "watched" field in recorded/videometadata to "watchedFlag".
DTC::EncoderList * GetEncoderList()
Definition: dvr.cpp:544
static QStringList GetNames(void)
Definition: playgroup.cpp:173
virtual QMap< QString, ProgramInfo * > GetRecording(void) const =0
bool RemoveRecordSchedule(uint RecordId)
Definition: dvr.cpp:1220
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:383
bool Load(bool asTemplate=false)
unsigned m_filter
QString m_category
Definition: recordingrule.h:80
bool LoadTemplate(QString category, QString categoryType="Default")
DTC::InputList * GetInputList()
Definition: dvr.cpp:615
bool LoadFromRecorded(ProgramList &destination, bool possiblyInProgressRecordingsOnly, const QMap< QString, uint32_t > &inUseMap, const QMap< QString, bool > &isJobRunning, const QMap< QString, ProgramInfo *> &recMap, int sort)
DTC::ProgramList * GetRecordedList(bool Descending, int StartIndex, int Count, const QString &TitleRegEx, const QString &RecGroup, const QString &StorageGroup)
Definition: dvr.cpp:62
std::deque< RecordingInfo * > RecList
Definition: mythscheduler.h:10
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:610
vector< ProgramInfo * > pginfolist_t
Definition: autoexpire.h:24
QStringList GetRecGroupList()
Definition: dvr.cpp:635
RecordingDupInType dupInFromString(QString type)
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:181
bool QueryPositionKeyFrame(uint64_t *, uint64_t position, bool backwards) const
void FillInputInfo(DTC::Input *input, InputInfo inputInfo)
bool MakeOverride(void)
bool DisableRecordSchedule(uint RecordId)
Definition: dvr.cpp:1398
QString GetHostName(void)
bool UpdateRecordSchedule(uint RecordId, QString Title, QString Subtitle, QString Description, QString Category, QDateTime StartTime, QDateTime EndTime, QString SeriesId, QString ProgramId, int ChanId, QString Station, int FindDay, QTime FindTime, bool Inactive, uint Season, uint Episode, QString Inetref, QString Type, QString SearchType, int RecPriority, uint PreferredInput, int StartOffset, int EndOffset, QString DupMethod, QString DupIn, 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: dvr.cpp:1061
bool GetAllPending(RecList &retList, int recRuleId=0) const
Definition: scheduler.cpp:1767
Default UTC.
Definition: mythdate.h:14
bool HasPathname(void) const
Definition: programinfo.h:339
bool EnableRecordSchedule(uint RecordId)
Definition: dvr.cpp:1378
QStringList GetTitleList(const QString &RecGroup)
Definition: dvr.cpp:703
RecSearchType m_searchType
bool QueryKeyFrameDuration(uint64_t *, uint64_t keyframe, bool backwards) const
uint AddRecordSchedule(QString Title, QString Subtitle, QString Description, QString Category, QDateTime StartTime, QDateTime EndTime, QString SeriesId, QString ProgramId, int ChanId, QString Station, int FindDay, QTime FindTime, int ParentId, bool Inactive, uint Season, uint Episode, QString Inetref, QString Type, QString SearchType, int RecPriority, uint PreferredInput, int StartOffset, int EndOffset, QString DupMethod, QString DupIn, 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: dvr.cpp:919
bool IsValid(QString &text)