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 nStartIndex,
147  int nCount,
148  const QDateTime &sStartTime,
149  const QDateTime &sEndTime,
150  const QString &sTitle,
151  const QString &sSeriesId,
152  int nRecordId,
153  const QString &sSort)
154 {
155  if (!sStartTime.isNull() && !sStartTime.isValid())
156  throw QString("StartTime is invalid");
157 
158  if (!sEndTime.isNull() && !sEndTime.isValid())
159  throw QString("EndTime is invalid");
160 
161  QDateTime dtStartTime = sStartTime;
162  QDateTime dtEndTime = sEndTime;
163 
164  if (!sEndTime.isNull() && dtEndTime < dtStartTime)
165  throw QString("EndTime is before StartTime");
166 
167  // ----------------------------------------------------------------------
168  // Build SQL statement for Program Listing
169  // ----------------------------------------------------------------------
170 
171  ProgramList progList;
172  MSqlBindings bindings;
173  QString sSQL;
174 
175  if (!dtStartTime.isNull())
176  {
177  sSQL += " AND endtime >= :StartDate ";
178  bindings[":StartDate"] = dtStartTime;
179  }
180 
181  if (!dtEndTime.isNull())
182  {
183  sSQL += " AND starttime <= :EndDate ";
184  bindings[":EndDate"] = dtEndTime;
185  }
186 
187  QStringList clause;
188 
189  if (nRecordId > 0)
190  {
191  clause << "recordid = :RecordId";
192  bindings[":RecordId"] = nRecordId;
193  }
194 
195  if (!sTitle.isEmpty())
196  {
197  clause << "title = :Title";
198  bindings[":Title"] = sTitle;
199  }
200 
201  if (!sSeriesId.isEmpty())
202  {
203  clause << "seriesid = :SeriesId";
204  bindings[":SeriesId"] = sSeriesId;
205  }
206 
207  if (!clause.isEmpty())
208  {
209  sSQL += QString(" AND (%1) ").arg(clause.join(" OR "));
210  }
211 
212  if (sSort == "starttime")
213  sSQL += "ORDER BY starttime ";
214  else if (sSort == "title")
215  sSQL += "ORDER BY title ";
216  else
217  sSQL += "ORDER BY starttime ";
218 
219  if (bDescending)
220  sSQL += "DESC ";
221  else
222  sSQL += "ASC ";
223 
224  uint nTotalAvailable = (nStartIndex == 0) ? 1 : 0;
225  LoadFromOldRecorded( progList, sSQL, bindings,
226  (uint)nStartIndex, (uint)nCount, nTotalAvailable );
227 
228  // ----------------------------------------------------------------------
229  // Build Response
230  // ----------------------------------------------------------------------
231 
232  DTC::ProgramList *pPrograms = new DTC::ProgramList();
233 
234  nCount = (int)progList.size();
235  int nEndIndex = (int)progList.size();
236 
237  for( int n = 0; n < nEndIndex; n++)
238  {
239  ProgramInfo *pInfo = progList[ n ];
240 
241  DTC::Program *pProgram = pPrograms->AddNewProgram();
242 
243  FillProgramInfo( pProgram, pInfo, true );
244  }
245 
246  // ----------------------------------------------------------------------
247 
248  pPrograms->setStartIndex ( nStartIndex );
249  pPrograms->setCount ( nCount );
250  pPrograms->setTotalAvailable( nTotalAvailable );
251  pPrograms->setAsOf ( MythDate::current() );
252  pPrograms->setVersion ( MYTH_BINARY_VERSION );
253  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
254 
255  return pPrograms;
256 }
257 
259 //
261 
263  int chanid, const QDateTime &recstarttsRaw)
264 {
265  if ((RecordedId <= 0) &&
266  (chanid <= 0 || !recstarttsRaw.isValid()))
267  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
268 
269  // TODO Should use RecordingInfo
270  ProgramInfo pi;
271  if (RecordedId > 0)
272  pi = ProgramInfo(RecordedId);
273  else
274  pi = ProgramInfo(chanid, recstarttsRaw.toUTC());
275 
276  DTC::Program *pProgram = new DTC::Program();
277  FillProgramInfo( pProgram, &pi, true );
278 
279  return pProgram;
280 }
281 
283 //
285 
286 bool Dvr::RemoveRecorded(int RecordedId,
287  int chanid, const QDateTime &recstarttsRaw,
288  bool forceDelete, bool allowRerecord)
289 {
290  return DeleteRecording(RecordedId, chanid, recstarttsRaw, forceDelete,
291  allowRerecord);
292 }
293 
294 
295 bool Dvr::DeleteRecording(int RecordedId,
296  int chanid, const QDateTime &recstarttsRaw,
297  bool forceDelete, bool allowRerecord)
298 {
299  if ((RecordedId <= 0) &&
300  (chanid <= 0 || !recstarttsRaw.isValid()))
301  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
302 
303  // TODO Should use RecordingInfo
304  ProgramInfo pi;
305  if (RecordedId > 0)
306  pi = ProgramInfo(RecordedId);
307  else
308  pi = ProgramInfo(chanid, recstarttsRaw.toUTC());
309 
310  if (pi.GetChanID() && pi.HasPathname())
311  {
312  QString cmd = QString("DELETE_RECORDING %1 %2 %3 %4")
313  .arg(pi.GetChanID())
315  .arg(forceDelete ? "FORCE" : "NO_FORCE")
316  .arg(allowRerecord ? "FORGET" : "NO_FORGET");
317  MythEvent me(cmd);
318 
319  gCoreContext->dispatch(me);
320  return true;
321  }
322 
323  return false;
324 }
325 
327 //
329 
330 bool Dvr::UnDeleteRecording(int RecordedId,
331  int chanid, const QDateTime &recstarttsRaw)
332 {
333  if ((RecordedId <= 0) &&
334  (chanid <= 0 || !recstarttsRaw.isValid()))
335  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
336 
337  RecordingInfo ri;
338  if (RecordedId > 0)
339  ri = RecordingInfo(RecordedId);
340  else
341  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
342 
343  if (ri.GetChanID() && ri.HasPathname())
344  {
345  QString cmd = QString("UNDELETE_RECORDING %1 %2")
346  .arg(ri.GetChanID())
348  MythEvent me(cmd);
349 
350  gCoreContext->dispatch(me);
351  return true;
352  }
353 
354  return false;
355 }
356 
358 //
360 
361 bool Dvr::StopRecording(int RecordedId)
362 {
363  if (RecordedId <= 0)
364  throw QString("RecordedId param is invalid.");
365 
366  RecordingInfo ri = RecordingInfo(RecordedId);
367 
368  if (ri.GetChanID())
369  {
370  QString cmd = QString("STOP_RECORDING %1 %2")
371  .arg(ri.GetChanID())
373  MythEvent me(cmd);
374 
375  gCoreContext->dispatch(me);
376  return true;
377  }
378  else
379  throw QString("RecordedId %1 not found").arg(RecordedId);
380 
381  return false;
382 }
383 
385 //
387 
388 bool Dvr::ReactivateRecording(int RecordedId)
389 {
390  if (RecordedId <= 0)
391  throw QString("RecordedId param is invalid.");
392 
393  RecordingInfo ri = RecordingInfo(RecordedId);
394 
395  ri.ReactivateRecording();
396 
397  return true;
398 }
399 
401 //
403 
405 {
406  QString cmd = QString("RESCHEDULE_RECORDINGS");
407  MythEvent me(cmd);
408 
409  gCoreContext->dispatch(me);
410  return true;
411 }
412 
414 //
416 
417 bool Dvr::UpdateRecordedWatchedStatus ( int RecordedId,
418  int chanid,
419  const QDateTime &recstarttsRaw,
420  bool watched)
421 {
422  if ((RecordedId <= 0) &&
423  (chanid <= 0 || !recstarttsRaw.isValid()))
424  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
425 
426  // TODO Should use RecordingInfo
427  ProgramInfo pi;
428  if (RecordedId > 0)
429  pi = ProgramInfo(RecordedId);
430  else
431  pi = ProgramInfo(chanid, recstarttsRaw.toUTC());
432 
433  if (pi.GetChanID() && pi.HasPathname())
434  {
435  pi.SaveWatched(watched);
436  return true;
437  }
438 
439  return false;
440 }
441 
443 //
445 
446 long Dvr::GetSavedBookmark( int RecordedId,
447  int chanid,
448  const QDateTime &recstarttsRaw,
449  const QString &offsettype )
450 {
451  if ((RecordedId <= 0) &&
452  (chanid <= 0 || !recstarttsRaw.isValid()))
453  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
454 
455  RecordingInfo ri;
456  if (RecordedId > 0)
457  ri = RecordingInfo(RecordedId);
458  else
459  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
460  uint64_t offset;
461  bool isend=true;
462  uint64_t position = ri.QueryBookmark();
463  if (offsettype.toLower() == "position"){
464  ri.QueryKeyFramePosition(&offset, position, isend);
465  return offset;
466  }
467  else if (offsettype.toLower() == "duration"){
468  ri.QueryKeyFrameDuration(&offset, position, isend);
469  return offset;
470  }
471  else
472  return position;
473 }
474 
476 //
478 
479 bool Dvr::SetSavedBookmark( int RecordedId,
480  int chanid,
481  const QDateTime &recstarttsRaw,
482  const QString &offsettype,
483  long Offset )
484 {
485  if ((RecordedId <= 0) &&
486  (chanid <= 0 || !recstarttsRaw.isValid()))
487  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
488 
489  if (Offset < 0)
490  throw QString("Offset must be >= 0.");
491 
492  RecordingInfo ri;
493  if (RecordedId > 0)
494  ri = RecordingInfo(RecordedId);
495  else
496  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
497  uint64_t position;
498  bool isend=true;
499  if (offsettype.toLower() == "position"){
500  if (!ri.QueryPositionKeyFrame(&position, Offset, isend))
501  return false;
502  }
503  else if (offsettype.toLower() == "duration"){
504  if (!ri.QueryDurationKeyFrame(&position, Offset, isend))
505  return false;
506  }
507  else
508  position = Offset;
509  ri.SaveBookmark(position);
510  return true;
511 }
512 
514 //
516 
518  int chanid,
519  const QDateTime &recstarttsRaw,
520  const QString &offsettype )
521 {
522  int marktype;
523  if ((RecordedId <= 0) &&
524  (chanid <= 0 || !recstarttsRaw.isValid()))
525  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
526 
527  RecordingInfo ri;
528  if (RecordedId > 0)
529  ri = RecordingInfo(RecordedId);
530  else
531  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
532 
533  DTC::CutList* pCutList = new DTC::CutList();
534  if (offsettype == "Position")
535  marktype = 1;
536  else if (offsettype == "Duration")
537  marktype = 2;
538  else
539  marktype = 0;
540 
541  FillCutList(pCutList, &ri, marktype);
542 
543  return pCutList;
544 }
545 
547 //
549 
551  int chanid,
552  const QDateTime &recstarttsRaw,
553  const QString &offsettype )
554 {
555  int marktype;
556  if ((RecordedId <= 0) &&
557  (chanid <= 0 || !recstarttsRaw.isValid()))
558  throw QString("Recorded ID or Channel ID and StartTime appears invalid.");
559 
560  RecordingInfo ri;
561  if (RecordedId > 0)
562  ri = RecordingInfo(RecordedId);
563  else
564  ri = RecordingInfo(chanid, recstarttsRaw.toUTC());
565 
566  DTC::CutList* pCutList = new DTC::CutList();
567  if (offsettype == "Position")
568  marktype = 1;
569  else if (offsettype == "Duration")
570  marktype = 2;
571  else
572  marktype = 0;
573 
574  FillCommBreak(pCutList, &ri, marktype);
575 
576  return pCutList;
577 }
578 
580 //
582 
584  const QString &offsettype )
585 {
586  MarkTypes marktype;
587  if (RecordedId <= 0)
588  throw QString("Recorded ID appears invalid.");
589 
590  RecordingInfo ri;
591  ri = RecordingInfo(RecordedId);
592 
593  DTC::CutList* pCutList = new DTC::CutList();
594  if (offsettype == "BYTES")
595  marktype = MARK_GOP_BYFRAME;
596  else if (offsettype == "DURATION")
597  marktype = MARK_DURATION_MS;
598  else
599  {
600  delete pCutList;
601  throw QString("Type must be 'BYTES' or 'DURATION'.");
602  }
603 
604  FillSeek(pCutList, &ri, marktype);
605 
606  return pCutList;
607 }
608 
610 //
612 
614  int nCount )
615 {
616  pginfolist_t infoList;
617 
618  if (expirer)
619  expirer->GetAllExpiring( infoList );
620 
621  // ----------------------------------------------------------------------
622  // Build Response
623  // ----------------------------------------------------------------------
624 
625  DTC::ProgramList *pPrograms = new DTC::ProgramList();
626 
627  nStartIndex = (nStartIndex > 0) ? min( nStartIndex, (int)infoList.size() ) : 0;
628  nCount = (nCount > 0) ? min( nCount, (int)infoList.size() ) : infoList.size();
629  int nEndIndex = min((nStartIndex + nCount), (int)infoList.size() );
630 
631  for( int n = nStartIndex; n < nEndIndex; n++)
632  {
633  ProgramInfo *pInfo = infoList[ n ];
634 
635  if (pInfo != NULL)
636  {
637  DTC::Program *pProgram = pPrograms->AddNewProgram();
638 
639  FillProgramInfo( pProgram, pInfo, true );
640 
641  delete pInfo;
642  }
643  }
644 
645  // ----------------------------------------------------------------------
646 
647  pPrograms->setStartIndex ( nStartIndex );
648  pPrograms->setCount ( nCount );
649  pPrograms->setTotalAvailable( infoList.size() );
650  pPrograms->setAsOf ( MythDate::current() );
651  pPrograms->setVersion ( MYTH_BINARY_VERSION );
652  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
653 
654  return pPrograms;
655 }
656 
658 //
660 
662 {
663 
664  DTC::EncoderList* pList = new DTC::EncoderList();
665 
666  QList<InputInfo> inputInfoList = CardUtil::GetAllInputInfo();
667  QMap<int, EncoderLink *>::Iterator iter = tvList.begin();
668 
669  for (; iter != tvList.end(); ++iter)
670  {
671  EncoderLink *elink = *iter;
672 
673  if (elink != NULL)
674  {
675  DTC::Encoder *pEncoder = pList->AddNewEncoder();
676 
677  pEncoder->setId ( elink->GetInputID() );
678  pEncoder->setState ( elink->GetState() );
679  pEncoder->setLocal ( elink->IsLocal() );
680  pEncoder->setConnected ( elink->IsConnected() );
681  pEncoder->setSleepStatus ( elink->GetSleepStatus() );
682  // pEncoder->setLowOnFreeSpace( elink->isLowOnFreeSpace());
683 
684  if (pEncoder->Local())
685  pEncoder->setHostName( gCoreContext->GetHostName() );
686  else
687  pEncoder->setHostName( elink->GetHostName() );
688 
689  QList<InputInfo>::iterator it = inputInfoList.begin();
690  for (; it < inputInfoList.end(); ++it)
691  {
692  InputInfo inputInfo = *it;
693  if (inputInfo.inputid == static_cast<uint>(elink->GetInputID()))
694  {
695  DTC::Input *input = pEncoder->AddNewInput();
696  FillInputInfo(input, inputInfo);
697  }
698  }
699 
700  switch ( pEncoder->State() )
701  {
705  {
706  ProgramInfo *pInfo = elink->GetRecording();
707 
708  if (pInfo)
709  {
710  DTC::Program *pProgram = pEncoder->Recording();
711 
712  FillProgramInfo( pProgram, pInfo, true, true );
713 
714  delete pInfo;
715  }
716 
717  break;
718  }
719 
720  default:
721  break;
722  }
723  }
724  }
725  return pList;
726 }
727 
729 //
731 
733 {
734  DTC::InputList *pList = new DTC::InputList();
735 
736  QList<InputInfo> inputInfoList = CardUtil::GetAllInputInfo();
737  QList<InputInfo>::iterator it = inputInfoList.begin();
738  for (; it < inputInfoList.end(); ++it)
739  {
740  InputInfo inputInfo = *it;
741  DTC::Input *input = pList->AddNewInput();
742  FillInputInfo(input, inputInfo);
743  }
744 
745  return pList;
746 }
747 
749 //
751 
752 QStringList Dvr::GetRecGroupList()
753 {
754  MSqlQuery query(MSqlQuery::InitCon());
755  query.prepare("SELECT recgroup FROM recgroups WHERE recgroup <> 'Deleted' "
756  "ORDER BY recgroup");
757 
758  QStringList result;
759  if (!query.exec())
760  {
761  MythDB::DBError("GetRecGroupList", query);
762  return result;
763  }
764 
765  while (query.next())
766  result << query.value(0).toString();
767 
768  return result;
769 }
770 
772 //
774 
776 {
778 }
779 
781 //
783 
785 {
786  return PlayGroup::GetNames();
787 }
788 
790 //
792 
794 {
796 
797  MSqlQuery query(MSqlQuery::InitCon());
798 
799  query.prepare("SELECT filterid, description, newruledefault "
800  "FROM recordfilter ORDER BY filterid");
801 
802  if (query.exec())
803  {
804  while (query.next())
805  {
806  DTC::RecRuleFilter* ruleFilter = filterList->AddNewRecRuleFilter();
807  ruleFilter->setId(query.value(0).toInt());
808  ruleFilter->setDescription(QObject::tr(query.value(1).toString()
809  .toUtf8().constData()));
810  }
811  }
812 
813  return filterList;
814 }
815 
817 //
819 
820 QStringList Dvr::GetTitleList(const QString& RecGroup)
821 {
822  MSqlQuery query(MSqlQuery::InitCon());
823 
824  QString querystr = "SELECT DISTINCT title FROM recorded "
825  "WHERE deletepending = 0";
826 
827  if (!RecGroup.isEmpty())
828  querystr += " AND recgroup = :RECGROUP";
829  else
830  querystr += " AND recgroup != 'Deleted'";
831 
832  querystr += " ORDER BY title";
833 
834  query.prepare(querystr);
835 
836  if (!RecGroup.isEmpty())
837  query.bindValue(":RECGROUP", RecGroup);
838 
839  QStringList result;
840  if (!query.exec())
841  {
842  MythDB::DBError("GetTitleList recorded", query);
843  return result;
844  }
845 
846  while (query.next())
847  result << query.value(0).toString();
848 
849  return result;
850 }
851 
853 //
855 
857 {
858  MSqlQuery query(MSqlQuery::InitCon());
859 
860  QString querystr = QString(
861  "SELECT title, inetref, count(title) as count "
862  " FROM recorded AS r "
863  " JOIN recgroups AS g ON r.recgroupid = g.recgroupid "
864  " WHERE g.recgroup NOT IN ('Deleted', 'LiveTV') "
865  " AND r.deletepending = 0 "
866  " GROUP BY title, inetref "
867  " ORDER BY title");
868 
869  query.prepare(querystr);
870 
871  DTC::TitleInfoList *pTitleInfos = new DTC::TitleInfoList();
872  if (!query.exec())
873  {
874  MythDB::DBError("GetTitleList recorded", query);
875  return pTitleInfos;
876  }
877 
878  while (query.next())
879  {
880  DTC::TitleInfo *pTitleInfo = pTitleInfos->AddNewTitleInfo();
881 
882  pTitleInfo->setTitle(query.value(0).toString());
883  pTitleInfo->setInetref(query.value(1).toString());
884  pTitleInfo->setCount(query.value(2).toInt());
885  }
886 
887  return pTitleInfos;
888 }
889 
891 //
893 
895  int nCount,
896  bool bShowAll,
897  int nRecordId,
898  int nRecStatus )
899 {
900  RecordingList recordingList; // Auto-delete deque
901  RecList tmpList; // Standard deque, objects must be deleted
902 
903  if (nRecordId <= 0)
904  nRecordId = -1;
905 
906  // NOTE: Fetching this information directly from the schedule is
907  // significantly faster than using ProgramInfo::LoadFromScheduler()
908  Scheduler *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler());
909  if (scheduler)
910  scheduler->GetAllPending(tmpList, nRecordId);
911 
912  // Sort the upcoming into only those which will record
913  RecList::iterator it = tmpList.begin();
914  for(; it < tmpList.end(); ++it)
915  {
916  if ((nRecStatus != 0) &&
917  ((*it)->GetRecordingStatus() != nRecStatus))
918  {
919  delete *it;
920  *it = NULL;
921  continue;
922  }
923 
924  if (!bShowAll && ((((*it)->GetRecordingStatus() >= RecStatus::Pending) &&
925  ((*it)->GetRecordingStatus() <= RecStatus::WillRecord)) ||
926  ((*it)->GetRecordingStatus() == RecStatus::Recorded) ||
927  ((*it)->GetRecordingStatus() == RecStatus::Conflict)) &&
928  ((*it)->GetRecordingEndTime() > MythDate::current()))
929  {
930  recordingList.push_back(new RecordingInfo(**it));
931  }
932  else if (bShowAll &&
933  ((*it)->GetRecordingEndTime() > MythDate::current()))
934  {
935  recordingList.push_back(new RecordingInfo(**it));
936  }
937 
938  delete *it;
939  *it = NULL;
940  }
941 
942  // ----------------------------------------------------------------------
943  // Build Response
944  // ----------------------------------------------------------------------
945 
946  DTC::ProgramList *pPrograms = new DTC::ProgramList();
947 
948  nStartIndex = (nStartIndex > 0) ? min( nStartIndex, (int)recordingList.size() ) : 0;
949  nCount = (nCount > 0) ? min( nCount, (int)recordingList.size() ) : recordingList.size();
950  int nEndIndex = min((nStartIndex + nCount), (int)recordingList.size() );
951 
952  for( int n = nStartIndex; n < nEndIndex; n++)
953  {
954  ProgramInfo *pInfo = recordingList[ n ];
955 
956  DTC::Program *pProgram = pPrograms->AddNewProgram();
957 
958  FillProgramInfo( pProgram, pInfo, true );
959  }
960 
961  // ----------------------------------------------------------------------
962 
963  pPrograms->setStartIndex ( nStartIndex );
964  pPrograms->setCount ( nCount );
965  pPrograms->setTotalAvailable( recordingList.size() );
966  pPrograms->setAsOf ( MythDate::current() );
967  pPrograms->setVersion ( MYTH_BINARY_VERSION );
968  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
969 
970  return pPrograms;
971 }
972 
974 //
976 
978  int nCount,
979  int nRecordId )
980 {
981  RecordingList recordingList; // Auto-delete deque
982  RecList tmpList; // Standard deque, objects must be deleted
983 
984  if (nRecordId <= 0)
985  nRecordId = -1;
986 
987  // NOTE: Fetching this information directly from the schedule is
988  // significantly faster than using ProgramInfo::LoadFromScheduler()
989  Scheduler *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler());
990  if (scheduler)
991  scheduler->GetAllPending(tmpList, nRecordId);
992 
993  // Sort the upcoming into only those which are conflicts
994  RecList::iterator it = tmpList.begin();
995  for(; it < tmpList.end(); ++it)
996  {
997  if (((*it)->GetRecordingStatus() == RecStatus::Conflict) &&
998  ((*it)->GetRecordingStartTime() >= MythDate::current()))
999  {
1000  recordingList.push_back(new RecordingInfo(**it));
1001  }
1002  delete *it;
1003  *it = NULL;
1004  }
1005 
1006  // ----------------------------------------------------------------------
1007  // Build Response
1008  // ----------------------------------------------------------------------
1009 
1010  DTC::ProgramList *pPrograms = new DTC::ProgramList();
1011 
1012  nStartIndex = (nStartIndex > 0) ? min( nStartIndex, (int)recordingList.size() ) : 0;
1013  nCount = (nCount > 0) ? min( nCount, (int)recordingList.size() ) : recordingList.size();
1014  int nEndIndex = min((nStartIndex + nCount), (int)recordingList.size() );
1015 
1016  for( int n = nStartIndex; n < nEndIndex; n++)
1017  {
1018  ProgramInfo *pInfo = recordingList[ n ];
1019 
1020  DTC::Program *pProgram = pPrograms->AddNewProgram();
1021 
1022  FillProgramInfo( pProgram, pInfo, true );
1023  }
1024 
1025  // ----------------------------------------------------------------------
1026 
1027  pPrograms->setStartIndex ( nStartIndex );
1028  pPrograms->setCount ( nCount );
1029  pPrograms->setTotalAvailable( recordingList.size() );
1030  pPrograms->setAsOf ( MythDate::current() );
1031  pPrograms->setVersion ( MYTH_BINARY_VERSION );
1032  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
1033 
1034  return pPrograms;
1035 }
1036 
1038  QString sTitle,
1039  QString sSubtitle,
1040  QString sDescription,
1041  QString sCategory,
1042  QDateTime recstarttsRaw,
1043  QDateTime recendtsRaw,
1044  QString sSeriesId,
1045  QString sProgramId,
1046  int nChanId,
1047  QString sStation,
1048  int nFindDay,
1049  QTime tFindTime,
1050  int nParentId,
1051  bool bInactive,
1052  uint nSeason,
1053  uint nEpisode,
1054  QString sInetref,
1055  QString sType,
1056  QString sSearchType,
1057  int nRecPriority,
1058  uint nPreferredInput,
1059  int nStartOffset,
1060  int nEndOffset,
1061  QString sDupMethod,
1062  QString sDupIn,
1063  uint nFilter,
1064  QString sRecProfile,
1065  QString sRecGroup,
1066  QString sStorageGroup,
1067  QString sPlayGroup,
1068  bool bAutoExpire,
1069  int nMaxEpisodes,
1070  bool bMaxNewest,
1071  bool bAutoCommflag,
1072  bool bAutoTranscode,
1073  bool bAutoMetaLookup,
1074  bool bAutoUserJob1,
1075  bool bAutoUserJob2,
1076  bool bAutoUserJob3,
1077  bool bAutoUserJob4,
1078  int nTranscoder)
1079 {
1080  QDateTime recstartts = recstarttsRaw.toUTC();
1081  QDateTime recendts = recendtsRaw.toUTC();
1082  RecordingRule rule;
1083  rule.LoadTemplate("Default");
1084 
1085  if (sType.isEmpty())
1086  sType = "single";
1087 
1088  if (sSearchType.isEmpty())
1089  sSearchType = "none";
1090 
1091  if (sDupMethod.isEmpty())
1092  sDupMethod = "subtitleanddescription";
1093 
1094  if (sDupIn.isEmpty())
1095  sDupIn = "all";
1096 
1097  rule.m_title = sTitle;
1098  rule.m_subtitle = sSubtitle;
1099  rule.m_description = sDescription;
1100 
1101  rule.m_startdate = recstartts.date();
1102  rule.m_starttime = recstartts.time();
1103  rule.m_enddate = recendts.date();
1104  rule.m_endtime = recendts.time();
1105 
1106  rule.m_type = recTypeFromString(sType);
1107  rule.m_searchType = searchTypeFromString(sSearchType);
1108  rule.m_dupMethod = dupMethodFromString(sDupMethod);
1109  rule.m_dupIn = dupInFromString(sDupIn);
1110 
1111  if (sRecProfile.isEmpty())
1112  sRecProfile = "Default";
1113 
1114  if (sRecGroup.isEmpty())
1115  sRecGroup = "Default";
1116 
1117  if (sStorageGroup.isEmpty())
1118  sStorageGroup = "Default";
1119 
1120  if (sPlayGroup.isEmpty())
1121  sPlayGroup = "Default";
1122 
1123  rule.m_category = sCategory;
1124  rule.m_seriesid = sSeriesId;
1125  rule.m_programid = sProgramId;
1126 
1127  rule.m_channelid = nChanId;
1128  rule.m_station = sStation;
1129 
1130  rule.m_findday = nFindDay;
1131  rule.m_findtime = tFindTime;
1132 
1133  rule.m_recProfile = sRecProfile;
1134  rule.m_recGroupID = RecordingInfo::GetRecgroupID(sRecGroup);
1135  if (rule.m_recGroupID == 0)
1137  rule.m_storageGroup = sStorageGroup;
1138  rule.m_playGroup = sPlayGroup;
1139 
1140  rule.m_parentRecID = nParentId;
1141  rule.m_isInactive = bInactive;
1142 
1143  rule.m_season = nSeason;
1144  rule.m_episode = nEpisode;
1145  rule.m_inetref = sInetref;
1146 
1147  rule.m_recPriority = nRecPriority;
1148  rule.m_prefInput = nPreferredInput;
1149  rule.m_startOffset = nStartOffset;
1150  rule.m_endOffset = nEndOffset;
1151  rule.m_filter = nFilter;
1152 
1153  rule.m_autoExpire = bAutoExpire;
1154  rule.m_maxEpisodes = nMaxEpisodes;
1155  rule.m_maxNewest = bMaxNewest;
1156 
1157  rule.m_autoCommFlag = bAutoCommflag;
1158  rule.m_autoTranscode = bAutoTranscode;
1159  rule.m_autoMetadataLookup = bAutoMetaLookup;
1160 
1161  rule.m_autoUserJob1 = bAutoUserJob1;
1162  rule.m_autoUserJob2 = bAutoUserJob2;
1163  rule.m_autoUserJob3 = bAutoUserJob3;
1164  rule.m_autoUserJob4 = bAutoUserJob4;
1165 
1166  rule.m_transcoder = nTranscoder;
1167 
1168  QString msg;
1169  if (!rule.IsValid(msg))
1170  throw msg;
1171 
1172  rule.Save();
1173 
1174  uint recid = rule.m_recordID;
1175 
1176  return recid;
1177 }
1178 
1180  QString sTitle,
1181  QString sSubtitle,
1182  QString sDescription,
1183  QString sCategory,
1184  QDateTime dStartTimeRaw,
1185  QDateTime dEndTimeRaw,
1186  QString sSeriesId,
1187  QString sProgramId,
1188  int nChanId,
1189  QString sStation,
1190  int nFindDay,
1191  QTime tFindTime,
1192  bool bInactive,
1193  uint nSeason,
1194  uint nEpisode,
1195  QString sInetref,
1196  QString sType,
1197  QString sSearchType,
1198  int nRecPriority,
1199  uint nPreferredInput,
1200  int nStartOffset,
1201  int nEndOffset,
1202  QString sDupMethod,
1203  QString sDupIn,
1204  uint nFilter,
1205  QString sRecProfile,
1206  QString sRecGroup,
1207  QString sStorageGroup,
1208  QString sPlayGroup,
1209  bool bAutoExpire,
1210  int nMaxEpisodes,
1211  bool bMaxNewest,
1212  bool bAutoCommflag,
1213  bool bAutoTranscode,
1214  bool bAutoMetaLookup,
1215  bool bAutoUserJob1,
1216  bool bAutoUserJob2,
1217  bool bAutoUserJob3,
1218  bool bAutoUserJob4,
1219  int nTranscoder)
1220 {
1221  if (nRecordId <= 0 )
1222  throw QString("Record ID is invalid.");
1223 
1224  RecordingRule pRule;
1225  pRule.m_recordID = nRecordId;
1226  pRule.Load();
1227 
1228  if (!pRule.IsLoaded())
1229  throw QString("Record ID does not exist.");
1230 
1231  QDateTime recstartts = dStartTimeRaw.toUTC();
1232  QDateTime recendts = dEndTimeRaw.toUTC();
1233 
1234  pRule.m_isInactive = bInactive;
1235  if (sType.isEmpty())
1236  sType = "single";
1237 
1238  if (sSearchType.isEmpty())
1239  sSearchType = "none";
1240 
1241  if (sDupMethod.isEmpty())
1242  sDupMethod = "subtitleanddescription";
1243 
1244  if (sDupIn.isEmpty())
1245  sDupIn = "all";
1246 
1247  pRule.m_type = recTypeFromString(sType);
1248  pRule.m_searchType = searchTypeFromString(sSearchType);
1249  pRule.m_dupMethod = dupMethodFromString(sDupMethod);
1250  pRule.m_dupIn = dupInFromString(sDupIn);
1251 
1252  if (sRecProfile.isEmpty())
1253  sRecProfile = "Default";
1254 
1255  if (sRecGroup.isEmpty())
1256  sRecGroup = "Default";
1257 
1258  if (sStorageGroup.isEmpty())
1259  sStorageGroup = "Default";
1260 
1261  if (sPlayGroup.isEmpty())
1262  sPlayGroup = "Default";
1263 
1264  if (!sTitle.isEmpty())
1265  pRule.m_title = sTitle;
1266 
1267  if (!sSubtitle.isEmpty())
1268  pRule.m_subtitle = sSubtitle;
1269 
1270  if(!sDescription.isEmpty())
1271  pRule.m_description = sDescription;
1272 
1273  if (!sCategory.isEmpty())
1274  pRule.m_category = sCategory;
1275 
1276  if (!sSeriesId.isEmpty())
1277  pRule.m_seriesid = sSeriesId;
1278 
1279  if (!sProgramId.isEmpty())
1280  pRule.m_programid = sProgramId;
1281 
1282  if (nChanId)
1283  pRule.m_channelid = nChanId;
1284  if (!sStation.isEmpty())
1285  pRule.m_station = sStation;
1286 
1287  pRule.m_startdate = recstartts.date();
1288  pRule.m_starttime = recstartts.time();
1289  pRule.m_enddate = recendts.date();
1290  pRule.m_endtime = recendts.time();
1291 
1292  pRule.m_findday = nFindDay;
1293  pRule.m_findtime = tFindTime;
1294 
1295  pRule.m_recProfile = sRecProfile;
1296  pRule.m_recGroupID = RecordingInfo::GetRecgroupID(sRecGroup);
1297  if (pRule.m_recGroupID == 0)
1299  pRule.m_storageGroup = sStorageGroup;
1300  pRule.m_playGroup = sPlayGroup;
1301 
1302  pRule.m_isInactive = bInactive;
1303 
1304  pRule.m_season = nSeason;
1305  pRule.m_episode = nEpisode;
1306  pRule.m_inetref = sInetref;
1307 
1308  pRule.m_recPriority = nRecPriority;
1309  pRule.m_prefInput = nPreferredInput;
1310  pRule.m_startOffset = nStartOffset;
1311  pRule.m_endOffset = nEndOffset;
1312  pRule.m_filter = nFilter;
1313 
1314  pRule.m_autoExpire = bAutoExpire;
1315  pRule.m_maxEpisodes = nMaxEpisodes;
1316  pRule.m_maxNewest = bMaxNewest;
1317 
1318  pRule.m_autoCommFlag = bAutoCommflag;
1319  pRule.m_autoTranscode = bAutoTranscode;
1320  pRule.m_autoMetadataLookup = bAutoMetaLookup;
1321 
1322  pRule.m_autoUserJob1 = bAutoUserJob1;
1323  pRule.m_autoUserJob2 = bAutoUserJob2;
1324  pRule.m_autoUserJob3 = bAutoUserJob3;
1325  pRule.m_autoUserJob4 = bAutoUserJob4;
1326 
1327  pRule.m_transcoder = nTranscoder;
1328 
1329  QString msg;
1330  if (!pRule.IsValid(msg))
1331  throw msg;
1332 
1333  bool bResult = pRule.Save();
1334 
1335  return bResult;
1336 }
1337 
1339 {
1340  bool bResult = false;
1341 
1342  if (nRecordId <= 0 )
1343  throw QString("Record ID does not exist.");
1344 
1345  RecordingRule pRule;
1346  pRule.m_recordID = nRecordId;
1347 
1348  bResult = pRule.Delete();
1349 
1350  return bResult;
1351 }
1352 
1353 bool Dvr::AddDontRecordSchedule(int nChanId, const QDateTime &dStartTime,
1354  bool bNeverRecord)
1355 {
1356  bool bResult = true;
1357 
1358  if (nChanId <= 0 || !dStartTime.isValid())
1359  throw QString("Program does not exist.");
1360 
1361  ProgramInfo *pi = LoadProgramFromProgram(nChanId, dStartTime.toUTC());
1362 
1363  if (!pi)
1364  throw QString("Program does not exist.");
1365 
1366  // Why RecordingInfo instead of ProgramInfo? Good question ...
1367  RecordingInfo recInfo = RecordingInfo(*pi);
1368 
1369  delete pi;
1370 
1371  if (bNeverRecord)
1372  {
1373  recInfo.ApplyNeverRecord();
1374  }
1375  else
1377 
1378  return bResult;
1379 }
1380 
1382  int nCount,
1383  const QString &Sort,
1384  bool Descending )
1385 {
1386  Scheduler::SchedSortColumn sortingColumn;
1387  if (Sort.toLower() == "lastrecorded")
1388  sortingColumn = Scheduler::kSortLastRecorded;
1389  else if (Sort.toLower() == "nextrecording")
1390  sortingColumn = Scheduler::kSortNextRecording;
1391  else if (Sort.toLower() == "title")
1392  sortingColumn = Scheduler::kSortTitle;
1393  else if (Sort.toLower() == "priority")
1394  sortingColumn = Scheduler::kSortPriority;
1395  else if (Sort.toLower() == "type")
1396  sortingColumn = Scheduler::kSortType;
1397  else
1398  sortingColumn = Scheduler::kSortTitle;
1399 
1400  RecList recList;
1401  Scheduler::GetAllScheduled(recList, sortingColumn, !Descending);
1402 
1403  // ----------------------------------------------------------------------
1404  // Build Response
1405  // ----------------------------------------------------------------------
1406 
1407  DTC::RecRuleList *pRecRules = new DTC::RecRuleList();
1408 
1409  nStartIndex = (nStartIndex > 0) ? min( nStartIndex, (int)recList.size() ) : 0;
1410  nCount = (nCount > 0) ? min( nCount, (int)recList.size() ) : recList.size();
1411  int nEndIndex = min((nStartIndex + nCount), (int)recList.size() );
1412 
1413  for( int n = nStartIndex; n < nEndIndex; n++)
1414  {
1415  RecordingInfo *info = recList[n];
1416 
1417  if (info != NULL)
1418  {
1419  DTC::RecRule *pRecRule = pRecRules->AddNewRecRule();
1420 
1421  FillRecRuleInfo( pRecRule, info->GetRecordingRule() );
1422  }
1423  }
1424 
1425  // ----------------------------------------------------------------------
1426 
1427  pRecRules->setStartIndex ( nStartIndex );
1428  pRecRules->setCount ( nCount );
1429  pRecRules->setTotalAvailable( recList.size() );
1430  pRecRules->setAsOf ( MythDate::current() );
1431  pRecRules->setVersion ( MYTH_BINARY_VERSION );
1432  pRecRules->setProtoVer ( MYTH_PROTO_VERSION );
1433 
1434  while (!recList.empty())
1435  {
1436  delete recList.back();
1437  recList.pop_back();
1438  }
1439 
1440  return pRecRules;
1441 }
1442 
1444  QString sTemplate,
1445  int nRecordedId,
1446  int nChanId,
1447  QDateTime dStartTimeRaw,
1448  bool bMakeOverride )
1449 {
1450  RecordingRule rule;
1451  QDateTime dStartTime = dStartTimeRaw.toUTC();
1452 
1453  if (nRecordId > 0)
1454  {
1455  rule.m_recordID = nRecordId;
1456  if (!rule.Load())
1457  throw QString("Record ID does not exist.");
1458  }
1459  else if (!sTemplate.isEmpty())
1460  {
1461  if (!rule.LoadTemplate(sTemplate))
1462  throw QString("Template does not exist.");
1463  }
1464  else if (nRecordedId > 0) // Loads from the Recorded/Recorded Program Table
1465  {
1466  // Despite the use of ProgramInfo, this only applies to Recordings.
1467  ProgramInfo recInfo(nRecordedId);
1468  if (!rule.LoadByProgram(&recInfo))
1469  throw QString("Recording does not exist");
1470  }
1471  else if (nChanId > 0 && dStartTime.isValid()) // Loads from Program Table, should NOT be used with recordings
1472  {
1473  // Despite the use of RecordingInfo, this only applies to programs in the
1474  // present or future, not to recordings? Confused yet?
1476  RecordingInfo info(nChanId, dStartTime, false, 0, &status);
1477  if (status != RecordingInfo::kFoundProgram)
1478  throw QString("Program does not exist.");
1479  RecordingRule *pRule = info.GetRecordingRule();
1480  if (bMakeOverride && rule.m_type != kSingleRecord &&
1481  rule.m_type != kOverrideRecord && rule.m_type != kDontRecord)
1482  pRule->MakeOverride();
1483  rule = *pRule;
1484  }
1485  else
1486  {
1487  throw QString("Invalid request.");
1488  }
1489 
1490  DTC::RecRule *pRecRule = new DTC::RecRule();
1491  FillRecRuleInfo( pRecRule, &rule );
1492 
1493  return pRecRule;
1494 }
1495 
1497 {
1498  bool bResult = false;
1499 
1500  if (nRecordId <= 0 )
1501  throw QString("Record ID appears invalid.");
1502 
1503  RecordingRule pRule;
1504  pRule.m_recordID = nRecordId;
1505  pRule.Load();
1506 
1507  if (pRule.IsLoaded())
1508  {
1509  pRule.m_isInactive = false;
1510  bResult = pRule.Save();
1511  }
1512 
1513  return bResult;
1514 }
1515 
1517 {
1518  bool bResult = false;
1519 
1520  if (nRecordId <= 0 )
1521  throw QString("Record ID appears invalid.");
1522 
1523  RecordingRule pRule;
1524  pRule.m_recordID = nRecordId;
1525  pRule.Load();
1526 
1527  if (pRule.IsLoaded())
1528  {
1529  pRule.m_isInactive = true;
1530  bResult = pRule.Save();
1531  }
1532 
1533  return bResult;
1534 }
1535 
1536 int Dvr::RecordedIdForPathname(const QString & pathname)
1537 {
1538  uint recordedid;
1539 
1540  if (!ProgramInfo::QueryRecordedIdFromPathname(pathname, recordedid))
1541  return -1;
1542 
1543  return recordedid;
1544 }
1545 
1547 {
1548  RecStatus::Type type = static_cast<RecStatus::Type>(RecStatus);
1549  return RecStatus::toString(type);
1550 }
1551 
1552 QString Dvr::RecStatusToDescription(int RecStatus, int recType,
1553  const QDateTime &StartTime)
1554 {
1555  //if (!StartTime.isValid())
1556  // throw QString("StartTime appears invalid.");
1557  RecStatus::Type rsType = static_cast<RecStatus::Type>(RecStatus);
1558  RecordingType recordingType = static_cast<RecordingType>(recType);
1559  return RecStatus::toDescription(rsType, recordingType, StartTime);
1560 }
1561 
1562 QString Dvr::RecTypeToString(QString recType)
1563 {
1564  bool ok;
1565  RecordingType enumType = static_cast<RecordingType>(recType.toInt(&ok, 10));
1566  if (ok)
1567  return toString(enumType);
1568  // RecordingType type = static_cast<RecordingType>(recType);
1569  return toString(recTypeFromString(recType));
1570 }
1571 
1572 QString Dvr::RecTypeToDescription(QString recType)
1573 {
1574  bool ok;
1575  RecordingType enumType = static_cast<RecordingType>(recType.toInt(&ok, 10));
1576  if (ok)
1577  return toDescription(enumType);
1578  // RecordingType type = static_cast<RecordingType>(recType);
1579  return toDescription(recTypeFromString(recType));
1580 }
1581 
1582 QString Dvr::DupInToString(QString DupIn)
1583 {
1584  // RecordingDupInType type= static_cast<RecordingDupInType>(DupIn);
1585  // return toString(type);
1586  return toString(dupInFromString(DupIn));
1587 }
1588 
1589 QString Dvr::DupInToDescription(QString DupIn)
1590 {
1591  // RecordingDupInType type= static_cast<RecordingDupInType>(DupIn);
1592  //return toDescription(type);
1593  return toDescription(dupInFromString(DupIn));
1594 }
1595 
1596 QString Dvr::DupMethodToString(QString DupMethod)
1597 {
1598  // RecordingDupMethodType method = static_cast<RecordingDupMethodType>(DupMethod);
1599  return toString(dupMethodFromString(DupMethod));
1600 }
1601 
1602 QString Dvr::DupMethodToDescription(QString DupMethod)
1603 {
1604  // RecordingDupMethodType method = static_cast<RecordingDupMethodType>(DupMethod);
1605  return toDescription(dupMethodFromString(DupMethod));
1606 }
QString RecStatusToString(int RecStatus)
Definition: dvr.cpp:1546
QString m_subtitle
Definition: recordingrule.h:76
bool DeleteRecording(int RecordedId, int ChanId, const QDateTime &StartTime, bool ForceDelete, bool AllowRerecord)
Definition: dvr.cpp:295
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:798
MythScheduler * GetScheduler(void)
DTC::ProgramList * GetConflictList(int StartIndex, int Count, int RecordId)
Definition: dvr.cpp:977
Program * AddNewProgram()
Definition: programList.h:86
void bindValue(const QString &placeholder, const QVariant &val)
Definition: mythdbcon.cpp:897
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:793
DTC::TitleInfoList * GetTitleInfoList()
Definition: dvr.cpp:856
SchedSortColumn
Definition: scheduler.h:90
ProgramInfo * LoadProgramFromProgram(const uint chanid, const QDateTime &starttime)
bool StopRecording(int RecordedId)
Definition: dvr.cpp:361
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:417
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:784
DTC::CutList * GetRecordedCutList(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType)
Definition: dvr.cpp:517
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:1602
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:1582
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:550
RecordingType m_type
Definition: recordingrule.h:99
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
RecordingDupMethodType m_dupMethod
DTC::RecRuleList * GetRecordScheduleList(int StartIndex, int Count, const QString &Sort, bool Descending)
Definition: dvr.cpp:1381
int RecordedIdForPathname(const QString &Filename)
Definition: dvr.cpp:1536
bool RescheduleRecordings(void)
Definition: dvr.cpp:404
DTC::ProgramList * GetExpiringList(int StartIndex, int Count)
Definition: dvr.cpp:613
bool SetSavedBookmark(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType, long Offset)
Definition: dvr.cpp:479
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:775
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:286
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:583
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:1596
long GetSavedBookmark(int RecordedId, int ChanId, const QDateTime &StartTime, const QString &OffsetType)
Definition: dvr.cpp:446
Input * AddNewInput()
Definition: inputList.h:59
bool ReactivateRecording(int RecordedId)
Definition: dvr.cpp:388
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:1552
QString RecTypeToString(QString RecType)
Definition: dvr.cpp:1562
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:555
bool IsDeletePending(void) const
Definition: programinfo.h:465
Internal representation of a recording rule, mirrors the record table.
Definition: recordingrule.h:31
static QList< InputInfo > GetAllInputInfo()
Definition: cardutil.cpp:1044
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:1572
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:1353
Encoder * AddNewEncoder()
Definition: encoderList.h:59
DTC::ProgramList * GetUpcomingList(int StartIndex, int Count, bool ShowAll, int RecordId, int RecStatus)
Definition: dvr.cpp:894
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:823
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:1443
bool UnDeleteRecording(int RecordedId, int ChanId, const QDateTime &StartTime)
Definition: dvr.cpp:330
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:1589
DTC::Program * GetRecorded(int RecordedId, int ChanId, const QDateTime &StartTime)
Definition: dvr.cpp:262
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:661
static QStringList GetNames(void)
Definition: playgroup.cpp:206
virtual QMap< QString, ProgramInfo * > GetRecording(void) const =0
bool RemoveRecordSchedule(uint RecordId)
Definition: dvr.cpp:1338
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:383
bool LoadFromOldRecorded(ProgramList &destination, const QString &sql, const MSqlBindings &bindings)
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:732
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
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:98
std::deque< RecordingInfo * > RecList
Definition: mythscheduler.h:10
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:623
vector< ProgramInfo * > pginfolist_t
Definition: autoexpire.h:24
QStringList GetRecGroupList()
Definition: dvr.cpp:752
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:1516
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:1179
bool GetAllPending(RecList &retList, int recRuleId=0) const
Definition: scheduler.cpp:1767
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)
Definition: dvr.cpp:145
Default UTC.
Definition: mythdate.h:14
bool HasPathname(void) const
Definition: programinfo.h:339
bool EnableRecordSchedule(uint RecordId)
Definition: dvr.cpp:1496
QStringList GetTitleList(const QString &RecGroup)
Definition: dvr.cpp:820
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:1037
bool IsValid(QString &text)