MythTV  master
recordinginfo.cpp
Go to the documentation of this file.
1 // POSIX headers
2 #include <sys/types.h>
3 
4 // C headers
5 #include <cstdlib>
6 
7 // Qt headers
8 #include <QMap>
9 
10 // MythTV headers
11 #include "recordinginfo.h"
12 #include "recordingrule.h"
13 #include "scheduledrecording.h"
14 #include "mythmiscutil.h"
15 #include "mythdate.h"
16 #include "mythcorecontext.h"
17 #include "programinfoupdater.h"
18 #include "jobqueue.h"
19 #include "mythdb.h"
20 #include "mythlogging.h"
21 
22 #define LOC QString("RecordingInfo(%1): ").arg(GetBasename())
23 
24 static inline QString null_to_empty(const QString &str)
25 {
26  return str.isEmpty() ? "" : str;
27 }
28 
30 // works only for integer divisors of 60
31 static const uint kUnknownProgramLength = 30;
32 
34  const QString &_title,
35  const QString &_sortTitle,
36  const QString &_subtitle,
37  const QString &_sortSubtitle,
38  const QString &_description,
39  uint _season,
40  uint _episode,
41  uint _totalepisodes,
42  const QString &_syndicatedepisode,
43  const QString &_category,
44 
45  uint _chanid,
46  const QString &_chanstr,
47  const QString &_chansign,
48  const QString &_channame,
49 
50  const QString &_recgroup,
51  const QString &_playgroup,
52 
53  const QString &_hostname,
54  const QString &_storagegroup,
55 
56  uint _year,
57  uint _partnumber,
58  uint _parttotal,
59 
60  const QString &_seriesid,
61  const QString &_programid,
62  const QString &_inetref,
63  const CategoryType _catType,
64 
65  int _recpriority,
66 
67  const QDateTime &_startts,
68  const QDateTime &_endts,
69  const QDateTime &_recstartts,
70  const QDateTime &_recendts,
71 
72  float _stars,
73  const QDate &_originalAirDate,
74 
75  bool _repeat,
76 
77  RecStatus::Type _oldrecstatus,
78  bool _reactivate,
79 
80  uint _recordid,
81  uint _parentid,
82  RecordingType _rectype,
83  RecordingDupInType _dupin,
84  RecordingDupMethodType _dupmethod,
85 
86  uint _sourceid,
87  uint _inputid,
88 
89  uint _findid,
90 
91  bool _commfree,
92  uint _subtitleType,
93  uint _videoproperties,
94  uint _audioproperties,
95  bool _future,
96  int _schedorder,
97  uint _mplexid,
98  uint _sgroupid,
99  const QString &_inputname) :
100  ProgramInfo(
101  _title, _sortTitle, _subtitle, _sortSubtitle,
102  _description, _season, _episode, _totalepisodes,
103  _category, _chanid, _chanstr, _chansign, _channame,
104  QString(), _recgroup, _playgroup,
105  _startts, _endts, _recstartts, _recendts,
106  _seriesid, _programid, _inetref, _inputname),
107  m_oldrecstatus(_oldrecstatus),
108  m_future(_future),
109  m_schedOrder(_schedorder),
110  m_mplexId(_mplexid),
111  m_sgroupId(_sgroupid),
112  m_desiredRecStartTs(_startts),
113  m_desiredRecEndTs(_endts)
114 {
115  m_hostname = _hostname;
116  m_storageGroup = _storagegroup;
117 
118  m_syndicatedEpisode = _syndicatedepisode;
119 
120  m_year = _year;
121  m_partNumber = _partnumber;
122  m_partTotal = _parttotal;
123  m_catType = _catType;
124 
125  m_recPriority = _recpriority;
126 
127  m_stars = clamp(_stars, 0.0F, 1.0F);
128  m_originalAirDate = _originalAirDate;
129  if (m_originalAirDate.isValid() && m_originalAirDate < QDate(1940, 1, 1))
130  m_originalAirDate = QDate();
131 
133  m_programFlags |= _repeat ? FL_REPEAT : 0;
135  m_programFlags |= _reactivate ? FL_REACTIVATE : 0;
137  m_programFlags |= _commfree ? FL_CHANCOMMFREE : 0;
138 
139  m_recordId = _recordid;
140  m_parentId = _parentid;
141  m_recType = _rectype;
142  m_dupIn = _dupin;
143  m_dupMethod = _dupmethod;
144 
145  m_sourceId = _sourceid;
146  m_inputId = _inputid;
147  m_findId = _findid;
148 
149  m_properties = ((_subtitleType << kSubtitlePropertyOffset) |
150  (_videoproperties << kVideoPropertyOffset) |
151  _audioproperties);
152 
153  if (m_recStartTs >= m_recEndTs)
154  {
155  // start/end-offsets are invalid so ignore
158  }
159 
161 }
162 
164  const QString &_title,
165  const QString &_sortTitle,
166  const QString &_subtitle,
167  const QString &_sortSubtitle,
168  const QString &_description,
169  uint _season,
170  uint _episode,
171  const QString &_category,
172 
173  uint _chanid,
174  const QString &_chanstr,
175  const QString &_chansign,
176  const QString &_channame,
177 
178  const QString &_recgroup,
179  const QString &_playgroup,
180 
181  const QString &_seriesid,
182  const QString &_programid,
183  const QString &_inetref,
184 
185  int _recpriority,
186 
187  const QDateTime &_startts,
188  const QDateTime &_endts,
189  const QDateTime &_recstartts,
190  const QDateTime &_recendts,
191 
192  RecStatus::Type _recstatus,
193 
194  uint _recordid,
195  RecordingType _rectype,
196  RecordingDupInType _dupin,
197  RecordingDupMethodType _dupmethod,
198 
199  uint _findid,
200 
201  bool _commfree) :
202  ProgramInfo(
203  _title, _sortTitle, _subtitle, _sortSubtitle,
204  _description, _season, _episode, 0,
205  _category, _chanid, _chanstr, _chansign, _channame,
206  QString(), _recgroup, _playgroup,
207  _startts, _endts, _recstartts, _recendts,
208  _seriesid, _programid, _inetref, ""),
209  m_desiredRecStartTs(_startts),
210  m_desiredRecEndTs(_endts)
211 {
212  m_recPriority = _recpriority;
213 
214  m_recStatus = _recstatus,
215 
216  m_recordId = _recordid;
217  m_recType = _rectype;
218  m_dupIn = _dupin;
219  m_dupMethod = _dupmethod;
220 
221  m_findId = _findid;
222 
224  m_programFlags |= _commfree ? FL_CHANCOMMFREE : 0;
225 
227 }
228 
238  uint _chanid, const QDateTime &desiredts,
239  bool genUnknown, uint maxHours, LoadStatus *status)
240 {
241  ProgramList schedList;
242  ProgramList progList;
243 
244  MSqlBindings bindings;
245  QString querystr = "WHERE program.chanid = :CHANID AND "
246  " program.starttime < :STARTTS1 AND "
247  " program.endtime > :STARTTS2 ";
248  bindings[":CHANID"] = QString::number(_chanid);
249  QDateTime query_startts = desiredts.addSecs(50 - desiredts.time().second());
250  bindings[":STARTTS1"] = query_startts;
251  bindings[":STARTTS2"] = query_startts;
252 
253  ::LoadFromScheduler(schedList);
254  LoadFromProgram(progList, querystr, bindings, schedList);
255 
256  if (!progList.empty())
257  {
258  ProgramInfo *pginfo = progList[0];
259 
260  if (maxHours > 0)
261  {
262  if (desiredts.secsTo(
263  pginfo->GetScheduledEndTime()) > (int)maxHours * 3600)
264  {
265  pginfo->SetScheduledEndTime(desiredts.addSecs(maxHours * 3600));
266  pginfo->SetRecordingEndTime(pginfo->GetScheduledEndTime());
267  }
268  }
269 
270  *this = *pginfo;
271  if (status)
272  *status = kFoundProgram;
273  return;
274  }
275 
276  m_recStartTs = m_startTs = desiredts;
277  m_recEndTs = m_endTs = desiredts;
278  m_lastModified = desiredts;
279 
281  query.prepare("SELECT chanid, channum, callsign, name, "
282  "commmethod, outputfilters "
283  "FROM channel "
284  "WHERE chanid = :CHANID");
285  query.bindValue(":CHANID", _chanid);
286 
287  if (!query.exec())
288  {
289  MythDB::DBError("Loading Program overlapping a datetime", query);
290  if (status)
291  *status = kNoProgram;
292  return;
293  }
294 
295  if (!query.next())
296  {
297  if (status)
298  *status = kNoProgram;
299  return;
300  }
301 
302  m_chanId = query.value(0).toUInt();
303  m_chanStr = query.value(1).toString();
304  m_chanSign = query.value(2).toString();
305  m_chanName = query.value(3).toString();
307  m_programFlags |= (query.value(4).toInt() == COMM_DETECT_COMMFREE) ?
308  FL_CHANCOMMFREE : 0;
309  m_chanPlaybackFilters = query.value(5).toString();
310 
311  {
312  QMutexLocker locker(&s_staticDataLock);
313  if (s_unknownTitle.isEmpty())
314  s_unknownTitle = gCoreContext->GetSetting("UnknownTitle");
316  }
317 
318  if (!genUnknown)
319  {
320  if (status)
321  *status = kFakedZeroMinProgram;
322  return;
323  }
324 
325  // Round endtime up to the next half-hour.
326  m_endTs = QDateTime(
327  m_endTs.date(),
328  QTime(m_endTs.time().hour(),
329  m_endTs.time().minute() / kUnknownProgramLength
330  * kUnknownProgramLength), Qt::UTC);
331  m_endTs = m_endTs.addSecs(kUnknownProgramLength * 60);
332 
333  // if under a minute, bump it up to the next half hour
334  if (m_startTs.secsTo(m_endTs) < 60)
335  m_endTs = m_endTs.addSecs(kUnknownProgramLength * 60);
336 
338 
339  // Find next program starttime
340  bindings.clear();
341  QDateTime nextstart = m_startTs;
342  querystr = "WHERE program.chanid = :CHANID AND "
343  " program.starttime > :STARTTS "
344  "GROUP BY program.starttime ORDER BY program.starttime LIMIT 1 ";
345  bindings[":CHANID"] = QString::number(_chanid);
346  bindings[":STARTTS"] = desiredts.addSecs(50 - desiredts.time().second());
347 
348  LoadFromProgram(progList, querystr, bindings, schedList);
349 
350  if (!progList.empty())
351  nextstart = (*progList.begin())->GetScheduledStartTime();
352 
353  if (nextstart > m_startTs && nextstart < m_recEndTs)
354  m_recEndTs = m_endTs = nextstart;
355 
356  if (status)
357  *status = kFakedLiveTVProgram;
358 
361 
363 }
364 
367  bool ignore_non_serialized_data)
368 {
369  bool is_same =
370  ((m_chanId != 0U) && m_recStartTs.isValid() && m_startTs.isValid() &&
371  m_chanId == other.GetChanID() &&
372  m_recStartTs == other.GetRecordingStartTime() &&
373  m_startTs == other.GetScheduledStartTime());
374 
375  ProgramInfo::clone(other, ignore_non_serialized_data);
376 
377  if (!is_same)
378  {
379  delete m_record;
380  m_record = nullptr;
381  }
382 
383  if (!ignore_non_serialized_data)
384  {
387  m_future = other.m_future;
388  m_schedOrder = other.m_schedOrder;
389  m_mplexId = other.m_mplexId;
390  m_sgroupId = other.m_sgroupId;
393  }
394 
395  delete m_recordingFile;
396  m_recordingFile = nullptr;
398 }
399 
402  bool ignore_non_serialized_data)
403 {
404  bool is_same =
405  ((m_chanId != 0U) && m_recStartTs.isValid() && m_startTs.isValid() &&
406  m_chanId == other.GetChanID() &&
407  m_recStartTs == other.GetRecordingStartTime() &&
408  m_startTs == other.GetScheduledStartTime());
409 
410  ProgramInfo::clone(other, ignore_non_serialized_data);
411 
412  if (!is_same)
413  {
414  delete m_record;
415  m_record = nullptr;
416  }
417 
420  m_future = false;
421  m_schedOrder = 0;
422  m_mplexId = 0;
423  m_sgroupId = 0;
424  m_desiredRecStartTs = QDateTime();
425  m_desiredRecEndTs = QDateTime();
426 
427  delete m_recordingFile;
428  m_recordingFile = nullptr;
430 }
431 
433 {
435 
436  delete m_record;
437  m_record = nullptr;
438 
441  m_future = false;
442  m_schedOrder = 0;
443  m_mplexId = 0;
444  m_sgroupId = 0;
445  m_desiredRecStartTs = QDateTime();
446  m_desiredRecEndTs = QDateTime();
447 
448  delete m_recordingFile;
449  m_recordingFile = nullptr;
450 }
451 
452 
457 {
458  delete m_record;
459  m_record = nullptr;
460 
461  delete m_recordingFile;
462  m_recordingFile = nullptr;
463 }
464 
471 {
472  if (m_record == nullptr)
473  {
474  m_record = new RecordingRule();
475  m_record->LoadByProgram(this);
476  }
477 
478  return m_record->m_type;
479 }
480 
487 {
488  if (m_record == nullptr)
489  {
490  m_record = new RecordingRule();
491  m_record->LoadByProgram(this);
492  }
493 
494  return m_record->m_recProfile;
495 }
496 
501 {
502  if (m_record == nullptr)
503  {
504  m_record = new RecordingRule();
505  m_record->LoadByProgram(this);
506  }
507 
508  int result = 0;
509 
511  result |= JOB_TRANSCODE;
513  result |= JOB_COMMFLAG;
515  result |= JOB_METADATA;
517  result |= JOB_USERJOB1;
519  result |= JOB_USERJOB2;
521  result |= JOB_USERJOB3;
523  result |= JOB_USERJOB4;
524 
525 
526  return result;
527 }
528 
533 {
535 
536  if (getRecordID() < 0)
537  {
538  LOG(VB_GENERAL, LOG_ERR,
539  "ProgInfo Error: ApplyRecordRecID(void) needs recordid");
540  return;
541  }
542 
543  query.prepare("UPDATE recorded "
544  "SET recordid = :RECID "
545  "WHERE chanid = :CHANID AND starttime = :START");
546 
547  if (m_recType == kOverrideRecord && m_parentId > 0)
548  query.bindValue(":RECID", m_parentId);
549  else
550  query.bindValue(":RECID", getRecordID());
551  query.bindValue(":CHANID", m_chanId);
552  query.bindValue(":START", m_recStartTs);
553 
554  if (!query.exec())
555  MythDB::DBError(LOC + "RecordID update", query);
556 }
557 
568 {
570  if (newstate == kOverrideRecord || newstate == kDontRecord)
572  m_record->m_type = newstate;
573 
574  if (save)
575  {
576  if (newstate == kNotRecording)
577  m_record->Delete();
578  else
579  m_record->Save();
580  }
581 }
582 
589 {
591  m_record->m_recPriority = newrecpriority;
592  m_record->Save();
593 }
594 
600 void RecordingInfo::ApplyRecordRecGroupChange(const QString &newrecgroup)
601 {
603 
604  int newrecgroupid = GetRecgroupID(newrecgroup);
605 
606  // Catchall - in the event that the group doesn't exist, then to avoid
607  // breakage, we need to create it
608  if (newrecgroupid == 0)
609  {
610  query.prepare("INSERT INTO recgroups SET recgroup = :NAME, "
611  "displayname = :DISPLAYNAME");
612  query.bindValue(":NAME", newrecgroup);
613  query.bindValue(":DISPLAYNAME", newrecgroup);
614 
615  if (query.exec())
616  newrecgroupid = query.lastInsertId().toInt();
617 
618  if (newrecgroupid <= 0)
619  {
620  LOG(VB_GENERAL, LOG_ERR, QString("Could not create recording group (%1). "
621  "Does it already exist?").arg(newrecgroup));
622  return;
623  }
624  }
625 
626  LOG(VB_GENERAL, LOG_NOTICE,
627  QString("ApplyRecordRecGroupChange: %1 to %2 (%3)").arg(m_recGroup)
628  .arg(newrecgroup)
629  .arg(newrecgroupid));
630 
631  query.prepare("UPDATE recorded"
632  " SET recgroup = :RECGROUP, "
633  " recgroupid = :RECGROUPID "
634  " WHERE chanid = :CHANID"
635  " AND starttime = :START ;");
636  query.bindValue(":RECGROUP", null_to_empty(newrecgroup));
637  query.bindValue(":RECGROUPID", newrecgroupid);
638  query.bindValue(":START", m_recStartTs);
639  query.bindValue(":CHANID", m_chanId);
640 
641  if (!query.exec())
642  MythDB::DBError("RecGroup update", query);
643 
644  m_recGroup = newrecgroup; // Deprecate in favour of recgroupid
645  //recgroupid = newrecgroupid;
646 
647  SendUpdateEvent();
648 }
649 
651 {
653 
654  QString newrecgroup;
655  if (newrecgroupid > 0)
656  {
657  newrecgroup = GetRecgroupString(newrecgroupid);
658 
659  query.prepare("UPDATE recorded"
660  " SET recgroup = :RECGROUP, "
661  " recgroupid = :RECGROUPID "
662  " WHERE chanid = :CHANID"
663  " AND starttime = :START ;");
664  query.bindValue(":RECGROUP", null_to_empty(newrecgroup));
665  query.bindValue(":RECGROUPID", newrecgroupid);
666  query.bindValue(":START", m_recStartTs);
667  query.bindValue(":CHANID", m_chanId);
668 
669  if (!query.exec())
670  MythDB::DBError("RecGroup update", query);
671 
672  m_recGroup = newrecgroup; // Deprecate in favour of recgroupid
673  //recgroupid = newrecgroupid;
674 
675  SendUpdateEvent();
676  }
677 
678  LOG(VB_GENERAL, LOG_NOTICE,
679  QString("ApplyRecordRecGroupChange: %1 to %2 (%3)").arg(m_recGroup)
680  .arg(newrecgroup)
681  .arg(newrecgroupid));
682 }
683 
689 void RecordingInfo::ApplyRecordPlayGroupChange(const QString &newplaygroup)
690 {
692 
693  query.prepare("UPDATE recorded"
694  " SET playgroup = :PLAYGROUP"
695  " WHERE chanid = :CHANID"
696  " AND starttime = :START ;");
697  query.bindValue(":PLAYGROUP", null_to_empty(newplaygroup));
698  query.bindValue(":START", m_recStartTs);
699  query.bindValue(":CHANID", m_chanId);
700 
701  if (!query.exec())
702  MythDB::DBError("PlayGroup update", query);
703 
704  m_playGroup = newplaygroup;
705 
706  SendUpdateEvent();
707 }
708 
714 void RecordingInfo::ApplyStorageGroupChange(const QString &newstoragegroup)
715 {
717 
718  query.prepare("UPDATE recorded"
719  " SET storagegroup = :STORAGEGROUP"
720  " WHERE chanid = :CHANID"
721  " AND starttime = :START ;");
722  query.bindValue(":STORAGEGROUP", null_to_empty(newstoragegroup));
723  query.bindValue(":START", m_recStartTs);
724  query.bindValue(":CHANID", m_chanId);
725 
726  if (!query.exec())
727  MythDB::DBError("StorageGroup update", query);
728 
729  m_storageGroup = newstoragegroup;
730 
731  SendUpdateEvent();
732 }
733 
741 void RecordingInfo::ApplyRecordRecTitleChange(const QString &newTitle,
742  const QString &newSubtitle, const QString &newDescription)
743 {
745  QString sql = "UPDATE recorded SET title = :TITLE, subtitle = :SUBTITLE ";
746  if (!newDescription.isNull())
747  sql += ", description = :DESCRIPTION ";
748  sql += " WHERE chanid = :CHANID AND starttime = :START ;";
749 
750  query.prepare(sql);
751  query.bindValue(":TITLE", newTitle);
752  query.bindValue(":SUBTITLE", null_to_empty(newSubtitle));
753  if (!newDescription.isNull())
754  query.bindValue(":DESCRIPTION", newDescription);
755  query.bindValue(":CHANID", m_chanId);
756  query.bindValue(":START", m_recStartTs);
757 
758  if (!query.exec())
759  MythDB::DBError("RecTitle update", query);
760 
761  m_title = newTitle;
762  m_subtitle = newSubtitle;
763  if (!newDescription.isNull())
764  m_description = newDescription;
765 
766  SendUpdateEvent();
767 }
768 
769 /* \fn RecordingInfo::ApplyTranscoderProfileChangeById(int id)
770  * \brief Sets the transcoder profile for a recording
771  * \param profileid is the 'id' field from recordingprofiles table.
772  */
774 {
776 
777  query.prepare("UPDATE recorded "
778  "SET transcoder = :PROFILEID "
779  "WHERE chanid = :CHANID "
780  "AND starttime = :START");
781  query.bindValue(":PROFILEID", id);
782  query.bindValue(":CHANID", m_chanId);
783  query.bindValue(":START", m_recStartTs);
784 
785  if (!query.exec())
786  MythDB::DBError(LOC + "unable to update transcoder "
787  "in recorded table", query);
788 }
789 
794 {
795  if (profile == "Default") // use whatever is already in the transcoder
796  return;
797 
799 
800  if (profile == "Autodetect")
801  {
802  query.prepare("UPDATE recorded "
803  "SET transcoder = 0 "
804  "WHERE chanid = :CHANID "
805  "AND starttime = :START");
806  query.bindValue(":CHANID", m_chanId);
807  query.bindValue(":START", m_recStartTs);
808 
809  if (!query.exec())
810  MythDB::DBError(LOC + "unable to update transcoder "
811  "in recorded table", query);
812  }
813  else
814  {
815  MSqlQuery pidquery(MSqlQuery::InitCon());
816  pidquery.prepare("SELECT r.id "
817  "FROM recordingprofiles r, profilegroups p "
818  "WHERE r.profilegroup = p.id "
819  "AND p.name = 'Transcoders' "
820  "AND r.name = :PROFILE ");
821  pidquery.bindValue(":PROFILE", profile);
822 
823  if (!pidquery.exec())
824  {
825  MythDB::DBError("ProgramInfo: unable to query transcoder "
826  "profile ID", query);
827  }
828  else if (pidquery.next())
829  {
830  query.prepare("UPDATE recorded "
831  "SET transcoder = :TRANSCODER "
832  "WHERE chanid = :CHANID "
833  "AND starttime = :START");
834  query.bindValue(":TRANSCODER", pidquery.value(0).toInt());
835  query.bindValue(":CHANID", m_chanId);
836  query.bindValue(":START", m_recStartTs);
837 
838  if (!query.exec())
839  MythDB::DBError(LOC + "unable to update transcoder "
840  "in recorded table", query);
841  }
842  else
843  {
844  LOG(VB_GENERAL, LOG_ERR,
845  "ProgramInfo: unable to query transcoder profile ID");
846  }
847  }
848 }
849 
855 {
859  AddHistory(true, true);
860 }
861 
866 {
868  if (curType == kNotRecording)
870 }
871 
876 {
878  return m_record;
879 }
880 
885 {
888  return m_recordId;
889 }
890 
892  uint chanid, const QDateTime& recstartts)
893 {
894  if (chanid < 1)
895  {
896  LOG(VB_RECORD, LOG_WARNING,
897  QString("QueryRecordedIdFromKey: Invalid chanid %1").arg(chanid));
898  return false;
899  }
900  if (!recstartts.isValid())
901  {
902  LOG(VB_RECORD, LOG_WARNING,
903  QString("QueryRecordedIdFromKey: Invalid start ts %1")
904  .arg(recstartts.toString()));
905  return false;
906  }
907 
909  query.prepare(
910  "SELECT recordedid FROM recorded "
911  "WHERE chanid = :CHANID AND starttime = :RECSTARTTS");
912  query.bindValue(":CHANID", chanid);
913  query.bindValue(":RECSTARTTS", recstartts);
914  if (query.exec() && query.next())
915  {
916  recordedid = query.value(0).toUInt();
917  return true;
918  }
919 
920  return false;
921 }
922 
931 void RecordingInfo::StartedRecording(const QString& ext)
932 {
933  QString dirname = m_pathname;
934 
935  if (!m_record)
936  {
937  m_record = new RecordingRule();
938  m_record->LoadByProgram(this);
939  }
940 
943 
944  int count = 0;
945  while (!InsertProgram(this, m_record) && count < 50)
946  {
947  m_recStartTs = m_recStartTs.addSecs(1);
949  count++;
950  }
951 
952  if (count >= 50)
953  {
954  LOG(VB_GENERAL, LOG_ERR, "Couldn't insert program");
955  return;
956  }
957 
958  m_pathname = dirname + "/" + m_pathname;
959 
960  LOG(VB_FILE, LOG_INFO, LOC + QString("StartedRecording: Recording to '%1'")
961  .arg(m_pathname));
962 
963 
965 
966  query.prepare("DELETE FROM recordedseek WHERE chanid = :CHANID"
967  " AND starttime = :START;");
968  query.bindValue(":CHANID", m_chanId);
969  query.bindValue(":START", m_recStartTs);
970 
971  if (!query.exec() || !query.isActive())
972  MythDB::DBError("Clear seek info on record", query);
973 
974  query.prepare("DELETE FROM recordedmarkup WHERE chanid = :CHANID"
975  " AND starttime = :START;");
976  query.bindValue(":CHANID", m_chanId);
977  query.bindValue(":START", m_recStartTs);
978 
979  if (!query.exec() || !query.isActive())
980  MythDB::DBError("Clear markup on record", query);
981 
982  query.prepare("REPLACE INTO recordedcredits"
983  " SELECT * FROM credits"
984  " WHERE chanid = :CHANID AND starttime = :START;");
985  query.bindValue(":CHANID", m_chanId);
986  query.bindValue(":START", m_startTs);
987  if (!query.exec() || !query.isActive())
988  MythDB::DBError("Copy program credits on record", query);
989 
990  query.prepare("REPLACE INTO recordedprogram"
991  " SELECT * from program"
992  " WHERE chanid = :CHANID AND starttime = :START"
993  " AND title = :TITLE;");
994  query.bindValue(":CHANID", m_chanId);
995  query.bindValue(":START", m_startTs);
996  query.bindValue(":TITLE", m_title);
997  if (!query.exec() || !query.isActive())
998  MythDB::DBError("Copy program data on record", query);
999 
1000  query.prepare("REPLACE INTO recordedrating"
1001  " SELECT * from programrating"
1002  " WHERE chanid = :CHANID AND starttime = :START;");
1003  query.bindValue(":CHANID", m_chanId);
1004  query.bindValue(":START", m_startTs);
1005  if (!query.exec() || !query.isActive())
1006  MythDB::DBError("Copy program ratings on record", query);
1007 
1008  // File
1009  if (!GetRecordingFile())
1011  RecordingFile *recFile = GetRecordingFile();
1012  recFile->m_fileName = GetBasename();
1013  recFile->m_storageDeviceID = GetHostname();
1014  recFile->m_storageGroup = GetStorageGroup();
1015  recFile->Save();
1016 
1017  SendAddedEvent();
1018 }
1019 
1021  const RecordingRule *rule)
1022 {
1023  QString inputname = pg->GetInputName();
1024  int recgroupid = GetRecgroupID(pg->m_recGroup);
1025 
1027 
1028  if (!query.exec("LOCK TABLES recorded WRITE"))
1029  {
1030  MythDB::DBError("InsertProgram -- lock", query);
1031  return false;
1032  }
1033 
1034  query.prepare(
1035  "SELECT recordid "
1036  " FROM recorded "
1037  " WHERE chanid = :CHANID AND "
1038  " starttime = :STARTS");
1039  query.bindValue(":CHANID", pg->m_chanId);
1040  query.bindValue(":STARTS", pg->m_recStartTs);
1041 
1042  bool err = true;
1043  if (!query.exec())
1044  {
1045  MythDB::DBError("InsertProgram -- select", query);
1046  }
1047  else if (query.next())
1048  {
1049  LOG(VB_GENERAL, LOG_ERR,
1050  QString("RecordingInfo::InsertProgram(%1): ")
1051  .arg(pg->toString()) + "recording already exists...");
1052  }
1053  else
1054  {
1055  err = false;
1056  }
1057 
1058  if (err)
1059  {
1060  if (!query.exec("UNLOCK TABLES"))
1061  MythDB::DBError("InsertProgram -- unlock tables", query);
1062  return false;
1063  }
1064 
1065  query.prepare(
1066  "INSERT INTO recorded "
1067  " (chanid, starttime, endtime, title, "
1068  " subtitle, description, season, episode, "
1069  " hostname, category, recgroup, autoexpire, "
1070  " recordid, seriesid, programid, inetref, "
1071  " stars, previouslyshown, originalairdate, "
1072  " findid, transcoder, playgroup, recpriority, "
1073  " basename, progstart, progend, profile, "
1074  " duplicate, storagegroup, inputname, recgroupid) "
1075  "VALUES"
1076  " (:CHANID, :STARTS, :ENDS, :TITLE, "
1077  " :SUBTITLE, :DESC, :SEASON, :EPISODE, "
1078  " :HOSTNAME, :CATEGORY, :RECGROUP, :AUTOEXP, "
1079  " :RECORDID, :SERIESID, :PROGRAMID, :INETREF, "
1080  " :STARS, :REPEAT, :ORIGAIRDATE, "
1081  " :FINDID, :TRANSCODER, :PLAYGROUP, :RECPRIORITY, "
1082  " :BASENAME, :PROGSTART, :PROGEND, :PROFILE, "
1083  " 0, :STORGROUP, :INPUTNAME, :RECGROUPID) "
1084  );
1085 
1086  if (pg->m_recType == kOverrideRecord)
1087  query.bindValue(":RECORDID", pg->m_parentId);
1088  else
1089  query.bindValue(":RECORDID", pg->m_recordId);
1090 
1091  if (pg->m_originalAirDate.isValid())
1092  {
1093  query.bindValue(":ORIGAIRDATE", pg->m_originalAirDate);
1094  // If there is no originalairdate use "year"
1095  }
1096  else if (pg->m_year >= 1940)
1097  {
1098  query.bindValue(":ORIGAIRDATE", QDate(pg->m_year,1,1));
1099  }
1100  else
1101  {
1102  query.bindValue(":ORIGAIRDATE", "0000-00-00");
1103  }
1104 
1105  query.bindValue(":CHANID", pg->m_chanId);
1106  query.bindValue(":STARTS", pg->m_recStartTs);
1107  query.bindValue(":ENDS", pg->m_recEndTs);
1108  query.bindValue(":TITLE", pg->m_title);
1109  query.bindValue(":SUBTITLE", null_to_empty(pg->m_subtitle));
1110  query.bindValue(":DESC", null_to_empty(pg->m_description));
1111  query.bindValue(":SEASON", pg->m_season);
1112  query.bindValue(":EPISODE", pg->m_episode);
1113  query.bindValue(":HOSTNAME", pg->m_hostname);
1114  query.bindValue(":CATEGORY", null_to_empty(pg->m_category));
1115  query.bindValue(":RECGROUP", null_to_empty(pg->m_recGroup));
1116  query.bindValue(":AUTOEXP", rule->m_autoExpire);
1117  query.bindValue(":SERIESID", null_to_empty(pg->m_seriesId));
1118  query.bindValue(":PROGRAMID", null_to_empty(pg->m_programId));
1119  query.bindValue(":INETREF", null_to_empty(pg->m_inetRef));
1120  query.bindValue(":FINDID", pg->m_findId);
1121  query.bindValue(":STARS", pg->m_stars);
1122  query.bindValue(":REPEAT", pg->IsRepeat());
1123  query.bindValue(":TRANSCODER", rule->m_transcoder);
1124  query.bindValue(":PLAYGROUP", pg->m_playGroup);
1125  query.bindValue(":RECPRIORITY", rule->m_recPriority);
1126  query.bindValue(":BASENAME", pg->m_pathname);
1127  query.bindValue(":STORGROUP", null_to_empty(pg->m_storageGroup));
1128  query.bindValue(":PROGSTART", pg->m_startTs);
1129  query.bindValue(":PROGEND", pg->m_endTs);
1130  query.bindValue(":PROFILE", null_to_empty(rule->m_recProfile));
1131  query.bindValue(":INPUTNAME", inputname);
1132  query.bindValue(":RECGROUPID", recgroupid);
1133 
1134  bool ok = query.exec() && (query.numRowsAffected() > 0);
1135  if (ok)
1136  {
1137  pg->SetRecordingID(query.lastInsertId().toUInt());
1138  }
1139  bool active = query.isActive();
1140 
1141  if (!query.exec("UNLOCK TABLES"))
1142  MythDB::DBError("InsertProgram -- unlock tables", query);
1143 
1144  if (!ok && !active)
1145  {
1146  MythDB::DBError("InsertProgram -- insert", query);
1147 
1148  }
1149  else if (pg->m_recordId > 0)
1150  {
1151  query.prepare("UPDATE channel SET last_record = NOW() "
1152  "WHERE chanid = :CHANID");
1153  query.bindValue(":CHANID", pg->GetChanID());
1154  if (!query.exec())
1155  MythDB::DBError("InsertProgram -- channel last_record", query);
1156 
1157  query.prepare("UPDATE record SET last_record = NOW() "
1158  "WHERE recordid = :RECORDID");
1159  query.bindValue(":RECORDID", pg->m_recordId);
1160  if (!query.exec())
1161  MythDB::DBError("InsertProgram -- record last_record", query);
1162 
1163  if (pg->m_recType == kOverrideRecord && pg->m_parentId > 0)
1164  {
1165  query.prepare("UPDATE record SET last_record = NOW() "
1166  "WHERE recordid = :PARENTID");
1167  query.bindValue(":PARENTID", pg->m_parentId);
1168  if (!query.exec())
1169  MythDB::DBError("InsertProgram -- record last_record override",
1170  query);
1171  }
1172  }
1173 
1174  return ok;
1175 }
1176 
1185 void RecordingInfo::FinishedRecording(bool allowReRecord)
1186 {
1188  query.prepare("UPDATE recorded SET endtime = :ENDTIME, "
1189  " duplicate = :DUPLICATE "
1190  "WHERE chanid = :CHANID AND "
1191  " starttime = :STARTTIME ");
1192  query.bindValue(":ENDTIME", m_recEndTs);
1193  query.bindValue(":CHANID", m_chanId);
1194  query.bindValue(":STARTTIME", m_recStartTs);
1195  query.bindValue(":DUPLICATE", !allowReRecord);
1196 
1197  if (!query.exec())
1198  MythDB::DBError("FinishedRecording update", query);
1199 
1201  if (!allowReRecord)
1202  {
1204 
1205  qint64 starttime = m_recStartTs.toSecsSinceEpoch();
1206  qint64 endtime = m_recEndTs.toSecsSinceEpoch();
1207  int64_t duration = (endtime - starttime) * 1000000;
1208  SaveTotalDuration(duration);
1209 
1210  QString msg = "Finished recording";
1211  QString msg_subtitle = m_subtitle.isEmpty() ? "" :
1212  QString(" \"%1\"").arg(m_subtitle);
1213  QString details = QString("%1%2: channel %3")
1214  .arg(m_title)
1215  .arg(msg_subtitle)
1216  .arg(m_chanId);
1217 
1218  LOG(VB_GENERAL, LOG_INFO, QString("%1 %2").arg(msg).arg(details));
1219  }
1220 
1221  SendUpdateEvent();
1222 }
1223 
1229 {
1231  query.prepare("UPDATE recorded SET endtime = :ENDTIME "
1232  "WHERE chanid = :CHANID AND "
1233  " starttime = :STARTTIME ");
1234  query.bindValue(":ENDTIME", m_recEndTs);
1235 
1236  query.bindValue(":CHANID", m_chanId);
1237  query.bindValue(":STARTTIME", m_recStartTs);
1238 
1239  if (!query.exec())
1240  MythDB::DBError("UpdateRecordingEnd update", query);
1241 
1242  SendUpdateEvent();
1243 }
1244 
1249 {
1250  MSqlQuery result(MSqlQuery::InitCon());
1251 
1252  result.prepare("UPDATE oldrecorded SET reactivate = 1 "
1253  "WHERE station = :STATION AND "
1254  " starttime = :STARTTIME AND "
1255  " title = :TITLE;");
1256  result.bindValue(":STARTTIME", m_startTs);
1257  result.bindValue(":TITLE", m_title);
1258  result.bindValue(":STATION", m_chanSign);
1259 
1260  if (!result.exec())
1261  MythDB::DBError("ReactivateRecording", result);
1262 
1264 }
1265 
1269 void RecordingInfo::AddHistory(bool resched, bool forcedup, bool future)
1270 {
1271  bool dup = (GetRecordingStatus() == RecStatus::Recorded || forcedup);
1274  LOG(VB_SCHEDULE, LOG_INFO, QString("AddHistory: %1/%2, %3, %4, %5/%6")
1275  .arg(int(rs)).arg(int(m_oldrecstatus)).arg(future).arg(dup)
1277  if (!future)
1279  if (dup)
1280  SetReactivated(false);
1281  uint erecid = m_parentId ? m_parentId : m_recordId;
1282 
1283  MSqlQuery result(MSqlQuery::InitCon());
1284 
1285  result.prepare("REPLACE INTO oldrecorded (chanid,starttime,"
1286  "endtime,title,subtitle,description,season,episode,"
1287  "category,seriesid,programid,inetref,findid,recordid,"
1288  "station,rectype,recstatus,duplicate,reactivate,generic,"
1289  "future) "
1290  "VALUES(:CHANID,:START,:END,:TITLE,:SUBTITLE,:DESC,:SEASON,"
1291  ":EPISODE,:CATEGORY,:SERIESID,:PROGRAMID,:INETREF,"
1292  ":FINDID,:RECORDID,:STATION,:RECTYPE,:RECSTATUS,:DUPLICATE,"
1293  ":REACTIVATE,:GENERIC,:FUTURE);");
1294  result.bindValue(":CHANID", m_chanId);
1295  result.bindValue(":START", m_startTs);
1296  result.bindValue(":END", m_endTs);
1297  result.bindValue(":TITLE", m_title);
1298  result.bindValue(":SUBTITLE", null_to_empty(m_subtitle));
1299  result.bindValue(":DESC", null_to_empty(m_description));
1300  result.bindValue(":SEASON", m_season);
1301  result.bindValue(":EPISODE", m_episode);
1302  result.bindValue(":CATEGORY", null_to_empty(m_category));
1303  result.bindValue(":SERIESID", null_to_empty(m_seriesId));
1304  result.bindValue(":PROGRAMID", null_to_empty(m_programId));
1305  result.bindValue(":INETREF", null_to_empty(m_inetRef));
1306  result.bindValue(":FINDID", m_findId);
1307  result.bindValue(":RECORDID", erecid);
1308  result.bindValue(":STATION", null_to_empty(m_chanSign));
1309  result.bindValue(":RECTYPE", m_recType);
1310  result.bindValue(":RECSTATUS", rs);
1311  result.bindValue(":DUPLICATE", dup);
1312  result.bindValue(":REACTIVATE", 0);
1313  result.bindValue(":GENERIC", IsGeneric());
1314  result.bindValue(":FUTURE", future);
1315 
1316  if (!result.exec())
1317  MythDB::DBError("addHistory", result);
1318 
1319  if (dup && m_findId)
1320  {
1321  result.prepare("REPLACE INTO oldfind (recordid, findid) "
1322  "VALUES(:RECORDID,:FINDID);");
1323  result.bindValue(":RECORDID", erecid);
1324  result.bindValue(":FINDID", m_findId);
1325 
1326  if (!result.exec())
1327  MythDB::DBError("addFindHistory", result);
1328  }
1329 
1330  // The adding of an entry to oldrecorded may affect near-future
1331  // scheduling decisions, so recalculate if told
1332  if (resched)
1333  ScheduledRecording::RescheduleCheck(*this, "AddHistory");
1334 }
1335 
1340 {
1341  uint erecid = m_parentId ? m_parentId : m_recordId;
1342 
1343  MSqlQuery result(MSqlQuery::InitCon());
1344 
1345  result.prepare("DELETE FROM oldrecorded WHERE title = :TITLE AND "
1346  "starttime = :START AND station = :STATION");
1347  result.bindValue(":TITLE", m_title);
1348  result.bindValue(":START", m_recStartTs);
1349  result.bindValue(":STATION", m_chanSign);
1350 
1351  if (!result.exec())
1352  MythDB::DBError("deleteHistory", result);
1353 
1354  if (/*m_duplicate &&*/ m_findId)
1355  {
1356  result.prepare("DELETE FROM oldfind WHERE "
1357  "recordid = :RECORDID AND findid = :FINDID");
1358  result.bindValue(":RECORDID", erecid);
1359  result.bindValue(":FINDID", m_findId);
1360 
1361  if (!result.exec())
1362  MythDB::DBError("deleteFindHistory", result);
1363  }
1364 
1365  // The removal of an entry from oldrecorded may affect near-future
1366  // scheduling decisions, so recalculate
1367  ScheduledRecording::RescheduleCheck(*this, "DeleteHistory");
1368 }
1369 
1379 {
1380  uint erecid = m_parentId ? m_parentId : m_recordId;
1381  uint din = m_dupIn;
1382  uint dmeth = m_dupMethod;
1383 
1384  if (din == kDupsUnset)
1385  din = kDupsInAll;
1386  if (dmeth == kDupCheckUnset)
1387  dmeth = kDupCheckSubThenDesc;
1388 
1389  MSqlQuery result(MSqlQuery::InitCon());
1390 
1391  // Handle this specific entry in recorded.
1392  result.prepare("UPDATE recorded SET duplicate = 0 "
1393  "WHERE chanid = :CHANID "
1394  "AND starttime = :STARTTIME "
1395  "AND title = :TITLE;");
1396  result.bindValue(":STARTTIME", m_recStartTs);
1397  result.bindValue(":TITLE", m_title);
1398  result.bindValue(":CHANID", m_chanId);
1399 
1400  if (!result.exec())
1401  MythDB::DBError("forgetRecorded1", result);
1402 
1403  // Handle other matching entries in recorded.
1404  if (din & kDupsInRecorded)
1405  {
1406  result.prepare(
1407  "UPDATE recorded SET duplicate = 0 "
1408  "WHERE duplicate = 1 AND "
1409  " title = :TITLE AND "
1410  " ( "
1411  " (:PROGRAMID1 <> '' AND "
1412  " :PROGRAMID2 = recorded.programid) "
1413  " OR "
1414  " ( "
1415  " (:PROGRAMID3 = '' OR recorded.programid = '' OR "
1416  " LEFT(:PROGRAMID4, LOCATE('/', :PROGRAMID5)) <> "
1417  " LEFT(recorded.programid, "
1418  " LOCATE('/', recorded.programid))) "
1419  " AND "
1420  " (((:DUPMETHOD1 & 0x02) = 0) OR (:SUBTITLE1 <> '' "
1421  " AND :SUBTITLE2 = recorded.subtitle)) "
1422  " AND "
1423  " (((:DUPMETHOD2 & 0x04) = 0) OR (:DESCRIPTION1 <> '' "
1424  " AND :DESCRIPTION2 = recorded.description)) "
1425  " AND "
1426  " (((:DUPMETHOD3 & 0x08) = 0) OR "
1427  " (:SUBTITLE3 <> '' AND "
1428  " (:SUBTITLE4 = recorded.subtitle OR "
1429  " (recorded.subtitle = '' AND "
1430  " :SUBTITLE5 = recorded.description))) OR "
1431  " (:SUBTITLE6 = '' AND :DESCRIPTION3 <> '' AND "
1432  " (:DESCRIPTION4 = recorded.subtitle OR "
1433  " (recorded.subtitle = '' AND "
1434  " :DESCRIPTION5 = recorded.description)))) "
1435  " ) "
1436  " )" );
1437  result.bindValue(":TITLE", m_title);
1438  result.bindValue(":SUBTITLE1", null_to_empty(m_subtitle));
1439  result.bindValue(":SUBTITLE2", null_to_empty(m_subtitle));
1440  result.bindValue(":SUBTITLE3", null_to_empty(m_subtitle));
1441  result.bindValue(":SUBTITLE4", null_to_empty(m_subtitle));
1442  result.bindValue(":SUBTITLE5", null_to_empty(m_subtitle));
1443  result.bindValue(":SUBTITLE6", null_to_empty(m_subtitle));
1444  result.bindValue(":DESCRIPTION1", null_to_empty(m_description));
1445  result.bindValue(":DESCRIPTION2", null_to_empty(m_description));
1446  result.bindValue(":DESCRIPTION3", null_to_empty(m_description));
1447  result.bindValue(":DESCRIPTION4", null_to_empty(m_description));
1448  result.bindValue(":DESCRIPTION5", null_to_empty(m_description));
1449  result.bindValue(":PROGRAMID1", null_to_empty(m_programId));
1450  result.bindValue(":PROGRAMID2", null_to_empty(m_programId));
1451  result.bindValue(":PROGRAMID3", null_to_empty(m_programId));
1452  result.bindValue(":PROGRAMID4", null_to_empty(m_programId));
1453  result.bindValue(":PROGRAMID5", null_to_empty(m_programId));
1454  result.bindValue(":DUPMETHOD1", dmeth);
1455  result.bindValue(":DUPMETHOD2", dmeth);
1456  result.bindValue(":DUPMETHOD3", dmeth);
1457 
1458  if (!result.exec())
1459  MythDB::DBError("forgetRecorded2", result);
1460  }
1461 
1462  // Handle this specific entry in oldrecorded.
1463  result.prepare("UPDATE oldrecorded SET duplicate = 0 "
1464  "WHERE station = :STATION "
1465  "AND starttime = :STARTTIME "
1466  "AND title = :TITLE;");
1467  result.bindValue(":STARTTIME", m_startTs);
1468  result.bindValue(":TITLE", m_title);
1469  result.bindValue(":STATION", m_chanSign);
1470 
1471  if (!result.exec())
1472  MythDB::DBError("forgetOldRecorded1", result);
1473 
1474  // Handle other matching entries in oldrecorded.
1475  if (din & kDupsInOldRecorded)
1476  {
1477  result.prepare(
1478  "UPDATE oldrecorded SET duplicate = 0 "
1479  "WHERE duplicate = 1 AND "
1480  " title = :TITLE AND "
1481  " ( "
1482  " (:PROGRAMID1 <> '' AND "
1483  " :PROGRAMID2 = oldrecorded.programid) "
1484  " OR "
1485  " ( "
1486  " (:PROGRAMID3 = '' OR oldrecorded.programid = '' OR "
1487  " LEFT(:PROGRAMID4, LOCATE('/', :PROGRAMID5)) <> "
1488  " LEFT(oldrecorded.programid, "
1489  " LOCATE('/', oldrecorded.programid))) "
1490  " AND "
1491  " (((:DUPMETHOD1 & 0x02) = 0) OR (:SUBTITLE1 <> '' "
1492  " AND :SUBTITLE2 = oldrecorded.subtitle)) "
1493  " AND "
1494  " (((:DUPMETHOD2 & 0x04) = 0) OR (:DESCRIPTION1 <> '' "
1495  " AND :DESCRIPTION2 = oldrecorded.description)) "
1496  " AND "
1497  " (((:DUPMETHOD3 & 0x08) = 0) OR "
1498  " (:SUBTITLE3 <> '' AND "
1499  " (:SUBTITLE4 = oldrecorded.subtitle OR "
1500  " (oldrecorded.subtitle = '' AND "
1501  " :SUBTITLE5 = oldrecorded.description))) OR "
1502  " (:SUBTITLE6 = '' AND :DESCRIPTION3 <> '' AND "
1503  " (:DESCRIPTION4 = oldrecorded.subtitle OR "
1504  " (oldrecorded.subtitle = '' AND "
1505  " :DESCRIPTION5 = oldrecorded.description)))) "
1506  " ) "
1507  " )" );
1508  result.bindValue(":TITLE", m_title);
1509  result.bindValue(":SUBTITLE1", null_to_empty(m_subtitle));
1510  result.bindValue(":SUBTITLE2", null_to_empty(m_subtitle));
1511  result.bindValue(":SUBTITLE3", null_to_empty(m_subtitle));
1512  result.bindValue(":SUBTITLE4", null_to_empty(m_subtitle));
1513  result.bindValue(":SUBTITLE5", null_to_empty(m_subtitle));
1514  result.bindValue(":SUBTITLE6", null_to_empty(m_subtitle));
1515  result.bindValue(":DESCRIPTION1", null_to_empty(m_description));
1516  result.bindValue(":DESCRIPTION2", null_to_empty(m_description));
1517  result.bindValue(":DESCRIPTION3", null_to_empty(m_description));
1518  result.bindValue(":DESCRIPTION4", null_to_empty(m_description));
1519  result.bindValue(":DESCRIPTION5", null_to_empty(m_description));
1520  result.bindValue(":PROGRAMID1", null_to_empty(m_programId));
1521  result.bindValue(":PROGRAMID2", null_to_empty(m_programId));
1522  result.bindValue(":PROGRAMID3", null_to_empty(m_programId));
1523  result.bindValue(":PROGRAMID4", null_to_empty(m_programId));
1524  result.bindValue(":PROGRAMID5", null_to_empty(m_programId));
1525  result.bindValue(":DUPMETHOD1", dmeth);
1526  result.bindValue(":DUPMETHOD2", dmeth);
1527  result.bindValue(":DUPMETHOD3", dmeth);
1528 
1529  if (!result.exec())
1530  MythDB::DBError("forgetOldRecorded2", result);
1531  }
1532 
1533  // Remove any never records which aren't need anymore.
1534  result.prepare("DELETE FROM oldrecorded "
1535  "WHERE recstatus = :NEVER AND duplicate = 0");
1536  result.bindValue(":NEVER", RecStatus::NeverRecord);
1537 
1538  if (!result.exec())
1539  MythDB::DBError("forgetNeverHistory", result);
1540 
1541  // Handle matching entries in oldfind.
1542  if (m_findId)
1543  {
1544  result.prepare("DELETE FROM oldfind WHERE "
1545  "recordid = :RECORDID AND findid = :FINDID");
1546  result.bindValue(":RECORDID", erecid);
1547  result.bindValue(":FINDID", m_findId);
1548 
1549  if (!result.exec())
1550  MythDB::DBError("forgetFindHistory", result);
1551  }
1552 
1553  // The removal of an entry from oldrecorded may affect near-future
1554  // scheduling decisions, so recalculate
1555  ScheduledRecording::RescheduleCheck(*this, "ForgetHistory");
1556 }
1557 
1562 {
1563  MSqlQuery result(MSqlQuery::InitCon());
1564 
1565  result.prepare("UPDATE oldrecorded SET duplicate = 1 "
1566  "WHERE future = 0 AND duplicate = 0 "
1567  "AND title = :TITLE AND "
1568  "((programid = '' AND subtitle = :SUBTITLE"
1569  " AND description = :DESC) OR "
1570  " (programid <> '' AND programid = :PROGRAMID) OR "
1571  " (findid <> 0 AND findid = :FINDID))");
1572  result.bindValue(":TITLE", m_title);
1573  result.bindValue(":SUBTITLE", null_to_empty(m_subtitle));
1574  result.bindValue(":DESC", null_to_empty(m_description));
1575  result.bindValue(":PROGRAMID", null_to_empty(m_programId));
1576  result.bindValue(":FINDID", m_findId);
1577 
1578  if (!result.exec())
1579  MythDB::DBError("setDupHistory", result);
1580 
1581  ScheduledRecording::RescheduleCheck(*this, "SetHistory");
1582 }
1583 
1589 {
1590  str.replace("%RECID%", QString::number(getRecordID()));
1591  str.replace("%PARENTID%", QString::number(m_parentId));
1592  str.replace("%FINDID%", QString::number(m_findId));
1593  str.replace("%RECSTATUS%", QString::number(m_recStatus));
1594  str.replace("%RECTYPE%", QString::number(m_recType));
1595  str.replace("%REACTIVATE%", IsReactivated() ? "1" : "0");
1596  str.replace("%INPUTNAME%", GetInputName());
1597  str.replace("%CHANNUM%", GetChanNum());
1598 
1600 }
1601 
1605 uint RecordingInfo::GetRecgroupID(const QString& recGroup)
1606 {
1608 
1609  query.prepare("SELECT recgroupid FROM recgroups WHERE recgroup = :RECGROUP");
1610  query.bindValue(":RECGROUP", null_to_empty(recGroup));
1611 
1612  if (!query.exec())
1613  MythDB::DBError("RecGroup update", query);
1614 
1615  if (!query.next())
1616  return 0;
1617 
1618  return query.value(0).toUInt();
1619 }
1620 
1625 {
1627 
1628  query.prepare("SELECT recgroup FROM recgroups WHERE recgroupid = :RECGROUPID");
1629  query.bindValue(":RECGROUPID", recGroupID);
1630  if (!query.exec() || !query.next())
1631  {
1632  MythDB::DBError("GetRecgroupString()", query);
1633  return QString();
1634  }
1635  return query.value(0).toString();
1636 }
1637 
1639 {
1640  if (!m_recordingFile)
1641  {
1643  if (m_recordedId > 0)
1644  {
1646  m_recordingFile->Load();
1647  }
1648  }
1649 }
1650 
1651 void RecordingInfo::SaveFilesize(uint64_t fsize)
1652 {
1653  if (!GetRecordingFile())
1655  GetRecordingFile()->m_fileSize = fsize;
1656  GetRecordingFile()->Save(); // Ideally this would be called just the once when all metadata is gathered
1657 
1659 
1660  ProgramInfo::SaveFilesize(fsize); // Temporary
1661 }
1662 
1663 void RecordingInfo::SetFilesize(uint64_t fsize)
1664 {
1665  if (!GetRecordingFile())
1667  GetRecordingFile()->m_fileSize = fsize;
1669 
1670  // Make sure the old storage location is updated for now
1671  ProgramInfo::SetFilesize(fsize);
1672 }
1673 
1674 uint64_t RecordingInfo::GetFilesize(void) const
1675 {
1677  return GetRecordingFile()->m_fileSize;
1678 
1679  // Temporary fallback to reading from old storage location
1680  return ProgramInfo::GetFilesize();
1681 }
1682 
1683 
1684 /* vim: set expandtab tabstop=4 shiftwidth=4: */
RecordingInfo::ApplyRecordPlayGroupChange
void ApplyRecordPlayGroupChange(const QString &newplaygroup)
Sets the recording group, both in this RecordingInfo and in the database.
Definition: recordinginfo.cpp:689
RecordingInfo::GetRecgroupID
static uint GetRecgroupID(const QString &recGroup)
Temporary helper during transition from string to ID.
Definition: recordinginfo.cpp:1605
JOB_USERJOB3
@ JOB_USERJOB3
Definition: jobqueue.h:80
MSqlBindings
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:98
ProgramInfo::m_startTs
QDateTime m_startTs
Definition: programinfo.h:778
JOB_USERJOB4
@ JOB_USERJOB4
Definition: jobqueue.h:81
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:204
RecordingRule::LoadByProgram
bool LoadByProgram(const ProgramInfo *proginfo)
Definition: recordingrule.cpp:168
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
RecStatus::Type
Type
Definition: recStatus.h:16
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:126
RecordingInfo::InsertProgram
static bool InsertProgram(RecordingInfo *pg, const RecordingRule *rule)
Definition: recordinginfo.cpp:1020
RecordingInfo::m_future
bool m_future
Definition: recordinginfo.h:278
ProgramInfo::SaveFilesize
virtual void SaveFilesize(uint64_t fsize)
Sets recording file size in database, and sets "filesize" field.
Definition: programinfo.cpp:6123
RecordingRule::m_autoTranscode
bool m_autoTranscode
Definition: recordingrule.h:133
ProgramInfo::m_fileSize
uint64_t m_fileSize
Definition: programinfo.h:776
RecordingInfo::QueryRecordedIdForKey
static bool QueryRecordedIdForKey(int &recordedid, uint chanid, const QDateTime &recstartts)
Definition: recordinginfo.cpp:891
RecordingInfo::FinishedRecording
void FinishedRecording(bool allowReRecord)
If not a premature stop, adds program to history of recorded programs.
Definition: recordinginfo.cpp:1185
ProgramInfo::GetFilesize
virtual uint64_t GetFilesize(void) const
Definition: programinfo.cpp:6154
RecordingInfo::ApplyNeverRecord
void ApplyNeverRecord(void)
Set this program to never be recorded by inserting 'history' for it into the database with a status o...
Definition: recordinginfo.cpp:854
ProgramInfo::m_recEndTs
QDateTime m_recEndTs
Definition: programinfo.h:781
RecordingInfo::m_oldrecstatus
RecStatus::Type m_oldrecstatus
Definition: recordinginfo.h:276
ProgramInfo::m_catType
CategoryType m_catType
Definition: programinfo.h:774
ProgramInfo::m_inputId
uint32_t m_inputId
Definition: programinfo.h:794
ProgramInfo::m_title
QString m_title
Definition: programinfo.h:743
RecordingRule::m_autoCommFlag
bool m_autoCommFlag
Definition: recordingrule.h:132
RecordingInfo::kFoundProgram
@ kFoundProgram
Definition: recordinginfo.h:181
ProgramInfo::SetRecordingStatus
void SetRecordingStatus(RecStatus::Type status)
Definition: programinfo.h:571
ProgramInfo::m_dupMethod
uint8_t m_dupMethod
Definition: programinfo.h:807
ProgramInfo::GetHostname
QString GetHostname(void) const
Definition: programinfo.h:419
ProgramInfo::m_storageGroup
QString m_storageGroup
Definition: programinfo.h:769
ProgramInfo::GetInputName
QString GetInputName(void) const
Definition: programinfo.h:462
ProgramInfo::m_chanId
uint32_t m_chanId
Definition: programinfo.h:757
mythdb.h
ProgramInfo::m_dupIn
uint8_t m_dupIn
Definition: programinfo.h:806
RecordingRule::Save
bool Save(bool sendSig=true)
Definition: recordingrule.cpp:383
RecordingInfo::m_desiredRecEndTs
QDateTime m_desiredRecEndTs
Definition: recordinginfo.h:283
RecordingInfo::ApplyRecordStateChange
void ApplyRecordStateChange(RecordingType newstate, bool save=true)
Sets RecordingType of "record", creating "record" if it does not exist.
Definition: recordinginfo.cpp:567
ProgramInfo::m_recordId
uint32_t m_recordId
Definition: programinfo.h:790
RecStatus::NeverRecord
@ NeverRecord
Definition: recStatus.h:43
ProgramInfo::m_recStartTs
QDateTime m_recStartTs
Definition: programinfo.h:780
RecordingInfo::ApplyRecordRecID
void ApplyRecordRecID(void)
Sets recordid to match RecordingRule recordid.
Definition: recordinginfo.cpp:532
kDupCheckSubThenDesc
@ kDupCheckSubThenDesc
Definition: recordingtypes.h:64
ProgramInfo::m_description
QString m_description
Definition: programinfo.h:747
ProgramInfo::s_staticDataLock
static QMutex s_staticDataLock
Definition: programinfo.h:828
RecordingInfo
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:35
RecordingInfo::GetFilesize
uint64_t GetFilesize(void) const override
Definition: recordinginfo.cpp:1674
RecordingInfo::ForgetHistory
void ForgetHistory(void)
Forget the recording of a program so it will be recorded again.
Definition: recordinginfo.cpp:1378
ProgramInfo::clone
virtual void clone(const ProgramInfo &other, bool ignore_non_serialized_data=false)
Copies important fields from other ProgramInfo.
Definition: programinfo.cpp:834
ProgramInfo::GetChanNum
QString GetChanNum(void) const
This is the channel "number", in the form 1, 1_2, 1-2, 1#1, etc.
Definition: programinfo.h:374
FL_REACTIVATE
@ FL_REACTIVATE
Definition: programtypes.h:147
RecordingInfo::SetFilesize
void SetFilesize(uint64_t fsize) override
Definition: recordinginfo.cpp:1663
MSqlQuery::lastInsertId
QVariant lastInsertId()
Return the id of the last inserted row.
Definition: mythdbcon.cpp:888
JOB_COMMFLAG
@ JOB_COMMFLAG
Definition: jobqueue.h:73
AutoDeleteDeque::empty
bool empty(void) const
Definition: autodeletedeque.h:66
null_to_empty
static QString null_to_empty(const QString &str)
Definition: recordinginfo.cpp:24
RecordingInfo::DeleteHistory
void DeleteHistory(void)
Deletes recording history, creating "record" it if necessary.
Definition: recordinginfo.cpp:1339
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:198
arg
arg(title).arg(filename).arg(doDelete))
RecordingInfo::GetProgramRecordingStatus
RecordingType GetProgramRecordingStatus(void)
Returns the recording type for this RecordingInfo, creating "record" field if necessary.
Definition: recordinginfo.cpp:470
RecStatus::Unknown
@ Unknown
Definition: recStatus.h:32
RecordingRule
Internal representation of a recording rule, mirrors the record table.
Definition: recordingrule.h:33
RecordingDupMethodType
RecordingDupMethodType
Definition: recordingtypes.h:58
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
ProgramInfo::m_recPriority
int32_t m_recPriority
Definition: programinfo.h:755
ProgramInfo::m_season
uint m_season
Definition: programinfo.h:748
RecordingFile
Holds information on a recording file and it's video and audio streams.
Definition: recordingfile.h:30
RecStatus::Recorded
@ Recorded
Definition: recStatus.h:29
ProgramInfo::SetScheduledStartTime
void SetScheduledStartTime(const QDateTime &dt)
Definition: programinfo.h:514
ProgramInfo::IsReactivated
bool IsReactivated(void) const
Definition: programinfo.h:486
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
ProgramInfo::GetScheduledEndTime
QDateTime GetScheduledEndTime(void) const
The scheduled end time of the program.
Definition: programinfo.h:395
ProgramInfo::m_pathname
QString m_pathname
Definition: programinfo.h:766
RecordingInfo::UpdateRecordingEnd
void UpdateRecordingEnd(void)
Update information in the recorded table when the end-time of a recording is changed.
Definition: recordinginfo.cpp:1228
ProgramInfo::m_endTs
QDateTime m_endTs
Definition: programinfo.h:779
RecordingInfo::s_unknownTitle
static QString s_unknownTitle
Definition: recordinginfo.h:293
RecordingInfo::getRecordID
int getRecordID(void)
Returns a record id, creating "record" it if necessary.
Definition: recordinginfo.cpp:884
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
kDupsInAll
@ kDupsInAll
Definition: recordingtypes.h:47
ProgramInfo::GetRecordingStartTime
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:402
ProgramInfo::SendAddedEvent
void SendAddedEvent(void) const
Sends event out that the ProgramInfo should be added to lists.
Definition: programinfo.cpp:2607
RecordingInfo::m_mplexId
uint m_mplexId
Definition: recordinginfo.h:280
JOB_USERJOB2
@ JOB_USERJOB2
Definition: jobqueue.h:79
RecordingInfo::ApplyTranscoderProfileChange
void ApplyTranscoderProfileChange(const QString &profile) const
Sets the transcoder profile for a recording.
Definition: recordinginfo.cpp:793
ProgramInfo::m_sourceId
uint32_t m_sourceId
Definition: programinfo.h:793
AutoDeleteDeque::begin
iterator begin(void)
Definition: autodeletedeque.h:50
kDupsInRecorded
@ kDupsInRecorded
Definition: recordingtypes.h:45
ProgramInfo::IsRepeat
bool IsRepeat(void) const
Definition: programinfo.h:484
RecordingInfo::ApplyStorageGroupChange
void ApplyStorageGroupChange(const QString &newstoragegroup)
Sets the storage group, both in this RecordingInfo and in the database.
Definition: recordinginfo.cpp:714
RecordingInfo::GetProgramRecordingProfile
QString GetProgramRecordingProfile(void) const
Returns recording profile name that will be, or was used, for this program, creating "record" field i...
Definition: recordinginfo.cpp:486
RecordingDupInType
RecordingDupInType
Definition: recordingtypes.h:43
ProgramInfo::m_hostname
QString m_hostname
Definition: programinfo.h:768
ProgramInfo::m_chanName
QString m_chanName
Definition: programinfo.h:760
mythdate.h
ProgramInfo::SetRecordingEndTime
void SetRecordingEndTime(const QDateTime &dt)
Definition: programinfo.h:517
RecordingInfo::GetRecordingFile
RecordingFile * GetRecordingFile() const
Definition: recordinginfo.h:271
COMM_DETECT_COMMFREE
@ COMM_DETECT_COMMFREE
Definition: programtypes.h:93
ProgramInfo::GetScheduledStartTime
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
Definition: programinfo.h:388
mythlogging.h
ProgramInfo::GetRecordingStatus
RecStatus::Type GetRecordingStatus(void) const
Definition: programinfo.h:445
RecordingInfo::m_savedrecstatus
RecStatus::Type m_savedrecstatus
Definition: recordinginfo.h:277
hardwareprofile.scan.profile
profile
Definition: scan.py:99
RecordingRule::m_autoUserJob4
bool m_autoUserJob4
Definition: recordingrule.h:137
ProgramInfo::m_recType
uint8_t m_recType
Definition: programinfo.h:805
ProgramInfo::m_category
QString m_category
Definition: programinfo.h:752
ProgramInfo::SetScheduledEndTime
void SetScheduledEndTime(const QDateTime &dt)
Definition: programinfo.h:515
RecStatus::PreviousRecording
@ PreviousRecording
Definition: recStatus.h:34
programinfoupdater.h
JOB_USERJOB1
@ JOB_USERJOB1
Definition: jobqueue.h:78
ProgramInfo::m_playGroup
QString m_playGroup
Definition: programinfo.h:764
RecordingInfo::m_desiredRecStartTs
QDateTime m_desiredRecStartTs
Definition: recordinginfo.h:282
RecordingInfo::SaveFilesize
void SaveFilesize(uint64_t fsize) override
Sets recording file size in database, and sets "filesize" field.
Definition: recordinginfo.cpp:1651
RecordingInfo::GetRecgroupString
static QString GetRecgroupString(uint recGroupID)
Temporary helper during transition from string to ID.
Definition: recordinginfo.cpp:1624
ProgramInfo::clear
virtual void clear(void)
Definition: programinfo.cpp:928
ProgramInfo::GetTitle
QString GetTitle(void) const
Definition: programinfo.h:359
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
ProgramInfo::m_seriesId
QString m_seriesId
Definition: programinfo.h:771
RecordingRule::m_autoUserJob2
bool m_autoUserJob2
Definition: recordingrule.h:135
RecordingFile::Save
bool Save()
Definition: recordingfile.cpp:55
RecordingInfo::RecordingInfo
RecordingInfo(void)
Definition: recordinginfo.h:37
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:178
kDupsInOldRecorded
@ kDupsInOldRecorded
Definition: recordingtypes.h:46
RecordingRule::m_autoExpire
bool m_autoExpire
Definition: recordingrule.h:127
RecordingInfo::GetAutoRunJobs
int GetAutoRunJobs(void) const
Returns a bitmap of which jobs are attached to this RecordingInfo.
Definition: recordinginfo.cpp:500
ProgramInfo::m_lastModified
QDateTime m_lastModified
Definition: programinfo.h:785
RecordingRule::m_recProfile
QString m_recProfile
Definition: recordingrule.h:121
ProgramInfo::m_episode
uint m_episode
Definition: programinfo.h:749
clamp
float clamp(float val, float minimum, float maximum)
Definition: mythmiscutil.h:59
kDupCheckUnset
@ kDupCheckUnset
Definition: recordingtypes.h:59
RecordingInfo::QuickRecord
void QuickRecord(void)
Create a kSingleRecord if not already scheduled.
Definition: recordinginfo.cpp:865
ProgramInfo::m_recGroup
QString m_recGroup
Definition: programinfo.h:763
RecordingRule::m_type
RecordingType m_type
Definition: recordingrule.h:113
FL_CHANCOMMFREE
@ FL_CHANCOMMFREE
Definition: programtypes.h:144
ProgramInfo::toString
QString toString(Verbosity v=kLongDescription, const QString &sep=":", const QString &grp="\"") const
Definition: programinfo.cpp:1825
ProgramInfoUpdater::insert
void insert(uint recordedid, PIAction action, uint64_t filesize=0ULL)
Definition: programinfoupdater.cpp:10
scheduledrecording.h
ScheduledRecording::RescheduleCheck
static void RescheduleCheck(const RecordingInfo &recinfo, const QString &why)
Definition: scheduledrecording.h:23
jobqueue.h
RecordingInfo::ReactivateRecording
void ReactivateRecording(void)
Asks the scheduler to restart this recording if possible.
Definition: recordinginfo.cpp:1248
RecordingInfo::StartedRecording
void StartedRecording(const QString &ext)
Inserts this RecordingInfo into the database as an existing recording.
Definition: recordinginfo.cpp:931
ProgramInfo::m_originalAirDate
QDate m_originalAirDate
Definition: programinfo.h:784
uint
unsigned int uint
Definition: compat.h:140
ProgramInfo::SetFilesize
virtual void SetFilesize(uint64_t sz)
Definition: programinfo.cpp:6113
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:56
ProgramInfo::LoadFromScheduler
static QStringList LoadFromScheduler(const QString &tmptable, int recordid)
Definition: programinfo.cpp:5323
RecordingInfo::LoadStatus
LoadStatus
Definition: recordinginfo.h:179
RecordingInfo::kNoProgram
@ kNoProgram
Definition: recordinginfo.h:180
ProgramInfo::CategoryType
CategoryType
Definition: programinfo.h:75
ProgramInfo::GetStorageGroup
QString GetStorageGroup(void) const
Definition: programinfo.h:420
ProgramInfo::m_recStatus
int8_t m_recStatus
Definition: programinfo.h:804
ScheduledRecording::ReschedulePlace
static void ReschedulePlace(const QString &why)
Definition: scheduledrecording.h:33
RecordingInfo::LoadRecordingFile
void LoadRecordingFile()
Definition: recordinginfo.cpp:1638
RecordingInfo::m_sgroupId
uint m_sgroupId
Definition: recordinginfo.h:281
RecordingFile::m_fileSize
uint64_t m_fileSize
Definition: recordingfile.h:45
kSubtitlePropertyOffset
#define kSubtitlePropertyOffset
Definition: programtypes.h:214
RecordingInfo::kFakedZeroMinProgram
@ kFakedZeroMinProgram
Definition: recordinginfo.h:183
RecordingInfo::m_schedOrder
int m_schedOrder
Definition: recordinginfo.h:279
AutoDeleteDeque< ProgramInfo * >
ProgramInfo::m_parentId
uint32_t m_parentId
Definition: programinfo.h:791
ProgramInfo::m_chanPlaybackFilters
QString m_chanPlaybackFilters
Definition: programinfo.h:761
recordinginfo.h
RecordingInfo::ApplyRecordRecPriorityChange
void ApplyRecordRecPriorityChange(int newrecpriority)
Sets recording priority of "record", creating "record" if it does not exist.
Definition: recordinginfo.cpp:588
ProgramInfo::GetChanID
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:370
kPIUpdateFileSize
@ kPIUpdateFileSize
Definition: programinfoupdater.h:22
RecordingRule::m_transcoder
int m_transcoder
Definition: recordingrule.h:131
RecordingRule::m_autoUserJob1
bool m_autoUserJob1
Definition: recordingrule.h:134
ProgramInfo::s_updater
static ProgramInfoUpdater * s_updater
Definition: programinfo.h:829
RecordingInfo::~RecordingInfo
~RecordingInfo() override
Destructor deletes "record" if it exists.
Definition: recordinginfo.cpp:456
RecordingInfo::SubstituteMatches
void SubstituteMatches(QString &str) override
Replace MATCH% vars in the specified string.
Definition: recordinginfo.cpp:1588
RecordingInfo::clone
virtual void clone(const RecordingInfo &other, bool ignore_non_serialized_data=false)
Copies important fields from other RecordingInfo.
Definition: recordinginfo.cpp:366
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:68
RecordingRule::m_recordID
int m_recordID
Unique Recording Rule ID.
Definition: recordingrule.h:72
ProgramInfo::m_inetRef
QString m_inetRef
Definition: programinfo.h:773
mythmiscutil.h
RecordingFile::m_recordingId
uint m_recordingId
Definition: recordingfile.h:38
ProgramInfo::SaveTotalDuration
void SaveTotalDuration(int64_t duration)
Store the Total Duration at frame 0 in the recordedmarkup table.
Definition: programinfo.cpp:4130
ProgramInfo::m_subtitle
QString m_subtitle
Definition: programinfo.h:745
mythcorecontext.h
kOverrideRecord
@ kOverrideRecord
Definition: recordingtypes.h:28
RecordingInfo::m_record
class RecordingRule * m_record
Definition: recordinginfo.h:286
ProgramInfo::m_syndicatedEpisode
QString m_syndicatedEpisode
Definition: programinfo.h:751
kNotRecording
@ kNotRecording
Definition: recordingtypes.h:21
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:864
JOB_METADATA
@ JOB_METADATA
Definition: jobqueue.h:74
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:14
ProgramInfo::m_findId
uint32_t m_findId
Definition: programinfo.h:795
RecStatus::CurrentRecording
@ CurrentRecording
Definition: recStatus.h:35
RecordingFile::m_fileName
QString m_fileName
Definition: recordingfile.h:44
LoadFromProgram
bool LoadFromProgram(ProgramList &destination, const QString &where, const QString &groupBy, const QString &orderBy, const MSqlBindings &bindings, const ProgramList &schedList)
Definition: programinfo.cpp:5458
RecordingInfo::clear
void clear(void) override
Definition: recordinginfo.cpp:432
LOC
#define LOC
Definition: recordinginfo.cpp:22
kSingleRecord
@ kSingleRecord
Definition: recordingtypes.h:22
ProgramInfo::m_chanSign
QString m_chanSign
Definition: programinfo.h:759
RecordingInfo::AddHistory
void AddHistory(bool resched=true, bool forcedup=false, bool future=false)
Adds recording history, creating "record" it if necessary.
Definition: recordinginfo.cpp:1269
ProgramInfo::SubstituteMatches
virtual void SubstituteMatches(QString &str)
Subsitute MATCH% type variable names in the given string.
Definition: programinfo.cpp:5210
RecordingInfo::ApplyTranscoderProfileChangeById
void ApplyTranscoderProfileChangeById(int id)
Definition: recordinginfo.cpp:773
kUnknownProgramLength
static const uint kUnknownProgramLength
Definition: recordinginfo.cpp:31
ProgramInfo::m_programFlags
uint32_t m_programFlags
ProgramFlag.
Definition: programinfo.h:797
ProgramInfo::m_partTotal
uint16_t m_partTotal
Definition: programinfo.h:802
ProgramInfo::m_chanStr
QString m_chanStr
Definition: programinfo.h:758
ProgramInfo::SendUpdateEvent
void SendUpdateEvent(void) const
Sends event out that the ProgramInfo should be reloaded.
Definition: programinfo.cpp:2602
RecordingInfo::kFakedLiveTVProgram
@ kFakedLiveTVProgram
Definition: recordinginfo.h:182
RecordingInfo::SetRecordingID
void SetRecordingID(uint _recordedid) override
Definition: recordinginfo.h:213
RecordingRule::Delete
bool Delete(bool sendSig=true)
Definition: recordingrule.cpp:501
RecordingRule::MakeOverride
bool MakeOverride(void)
Definition: recordingrule.cpp:361
MSqlQuery::numRowsAffected
int numRowsAffected() const
Definition: mythdbcon.h:206
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:855
ProgramInfo::m_partNumber
uint16_t m_partNumber
Definition: programinfo.h:801
RecordingInfo::ApplyRecordRecTitleChange
void ApplyRecordRecTitleChange(const QString &newTitle, const QString &newSubtitle, const QString &newDescription)
Sets the recording title, subtitle, and description both in this RecordingInfo and in the database.
Definition: recordinginfo.cpp:741
RecordingInfo::m_recordingFile
RecordingFile * m_recordingFile
Definition: recordinginfo.h:287
RecordingFile::Load
bool Load()
Definition: recordingfile.cpp:7
FL_REPEAT
@ FL_REPEAT
Definition: programtypes.h:145
RecordingInfo::GetRecordingRule
RecordingRule * GetRecordingRule(void)
Returns the "record" field, creating it if necessary.
Definition: recordinginfo.cpp:875
RecordingInfo::ApplyRecordRecGroupChange
void ApplyRecordRecGroupChange(const QString &newrecgroup)
Sets the recording group, both in this RecordingInfo and in the database.
Definition: recordinginfo.cpp:600
ProgramInfo::m_programId
QString m_programId
Definition: programinfo.h:772
recordingrule.h
ProgramInfo::m_stars
float m_stars
Rating, range [0..1].
Definition: programinfo.h:783
RecordingRule::m_recPriority
int m_recPriority
Definition: recordingrule.h:109
RecordingFile::m_storageGroup
QString m_storageGroup
Definition: recordingfile.h:41
ProgramInfo::m_year
uint16_t m_year
Definition: programinfo.h:800
ProgramInfo::GetBasename
QString GetBasename(void) const
Definition: programinfo.h:342
RecordingRule::m_autoUserJob3
bool m_autoUserJob3
Definition: recordingrule.h:136
kVideoPropertyOffset
#define kVideoPropertyOffset
Definition: programtypes.h:200
ProgramInfo::SetReactivated
void SetReactivated(bool reactivate)
Definition: programinfo.h:532
ProgramInfo::IsGeneric
bool IsGeneric(void) const
Definition: programinfo.cpp:1816
query
MSqlQuery query(MSqlQuery::InitCon())
JOB_TRANSCODE
@ JOB_TRANSCODE
Definition: jobqueue.h:72
ProgramInfo::m_recordedId
uint m_recordedId
Definition: programinfo.h:809
ProgramInfo::CreateRecordBasename
QString CreateRecordBasename(const QString &ext) const
Returns a filename for a recording based on the recording channel and date.
Definition: programinfo.cpp:2282
RecordingType
RecordingType
Definition: recordingtypes.h:20
kDontRecord
@ kDontRecord
Definition: recordingtypes.h:29
ProgramInfo::m_properties
uint16_t m_properties
SubtitleType,VideoProperty,AudioProperty.
Definition: programinfo.h:799
RecordingRule::m_autoMetadataLookup
bool m_autoMetadataLookup
Definition: recordingrule.h:138
kDupsUnset
@ kDupsUnset
Definition: recordingtypes.h:44
RecordingFile::m_storageDeviceID
QString m_storageDeviceID
Definition: recordingfile.h:40
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:915
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:808
RecordingInfo::SetDupHistory
void SetDupHistory(void)
Set the duplicate flag in oldrecorded.
Definition: recordinginfo.cpp:1561