MythTV  master
recordingutils.cpp
Go to the documentation of this file.
1 
2 // C++ includes
3 #include <algorithm> // for max
4 #include <iostream> // for cout, endl
5 #include <sys/stat.h>
6 
7 // Qt
8 #include <QFileInfo>
9 #include <QScopedPointer>
10 
11 // libmyth* includes
12 #include "exitcodes.h"
13 #include "mythlogging.h"
14 #include "remoteutil.h"
15 #include "remotefile.h"
16 #include "mythsystem.h"
17 #include "mythdirs.h"
18 
19 // Local includes
20 #include "recordingutils.h"
21 
22 static QString formatSize(int64_t sizeKB, int prec)
23 {
24  if (sizeKB>1024*1024*1024) // Terabytes
25  {
26  double sizeGB = sizeKB/(1024*1024*1024.0);
27  return QString("%1 TB").arg(sizeGB, 0, 'f', (sizeGB>10)?0:prec);
28  }
29  if (sizeKB>1024*1024) // Gigabytes
30  {
31  double sizeGB = sizeKB/(1024*1024.0);
32  return QString("%1 GB").arg(sizeGB, 0, 'f', (sizeGB>10)?0:prec);
33  }
34  if (sizeKB>1024) // Megabytes
35  {
36  double sizeMB = sizeKB/1024.0;
37  return QString("%1 MB").arg(sizeMB, 0, 'f', (sizeMB>10)?0:prec);
38  }
39  // Kilobytes
40  return QString("%1 KB").arg(sizeKB);
41 }
42 
43 static QString CreateProgramInfoString(const ProgramInfo &pginfo)
44 {
45  QDateTime recstartts = pginfo.GetRecordingStartTime();
46  QDateTime recendts = pginfo.GetRecordingEndTime();
47 
48  QString timedate = QString("%1 - %2")
49  .arg(MythDate::toString(
51  .arg(MythDate::toString(recendts, MythDate::kTime));
52 
53  QString title = pginfo.GetTitle();
54 
55  QString extra;
56 
57  if (!pginfo.GetSubtitle().isEmpty())
58  {
59  extra = QString(" ~ ") + pginfo.GetSubtitle();
60  int maxll = std::max(title.length(), 20);
61  if (extra.length() > maxll)
62  extra = extra.left(maxll - 3) + "...";
63  }
64 
65  return QString("%1%2 - %3").arg(title).arg(extra).arg(timedate);
66 }
67 
69 {
70  std::cout << "Checking Recordings" << std::endl;
71 
72  std::vector<ProgramInfo *> *recordingList = RemoteGetRecordedList(-1);
73  std::vector<ProgramInfo *> missingRecordings;
74  std::vector<ProgramInfo *> zeroByteRecordings;
75  std::vector<ProgramInfo *> noSeektableRecordings;
76 
77  if (!recordingList)
78  {
79  std::cout << "ERROR - failed to get recording list from backend" << std::endl;
80  return GENERIC_EXIT_NOT_OK;
81  }
82 
83  bool fixSeektable = cmdline.toBool("fixseektable");
84 
85  std::cout << "Fix seektable is: " << fixSeektable << std::endl;
86 
87  if (!recordingList->empty())
88  {
89  for (auto i = recordingList->begin(); i != recordingList->end(); ++i)
90  {
91  ProgramInfo *p = *i;
92  // ignore live tv and deleted recordings
93  if (p->GetRecordingGroup() == "LiveTV" ||
94  p->GetRecordingGroup() == "Deleted")
95  {
96  i = recordingList->erase(i);
97  --i;
98  continue;
99  }
100 
101  std::cout << "Checking: " << qPrintable(CreateProgramInfoString(*p)) << std::endl;
102  bool foundFile = true;
103 
104  QString url = p->GetPlaybackURL();
105 
106  if (url.startsWith('/'))
107  {
108  QFileInfo fi(url);
109  if (!fi.exists())
110  {
111  std::cout << "File not found" << std::endl;
112  missingRecordings.push_back(p);
113  foundFile = false;
114  }
115  else
116  {
117  if (fi.size() == 0)
118  {
119  std::cout << "File was found but has zero length" << std::endl;
120  zeroByteRecordings.push_back(p);
121  }
122  }
123  }
124  else if (url.startsWith("myth:"))
125  {
126  if (!RemoteFile::Exists(url))
127  {
128  std::cout << "File not found" << std::endl;
129  missingRecordings.push_back(p);
130  foundFile = false;
131  }
132  else
133  {
134  RemoteFile rf(url);
135  if (rf.GetFileSize() == 0)
136  {
137  std::cout << "File was found but has zero length" << std::endl;
138  zeroByteRecordings.push_back(p);
139  }
140  }
141  }
142 
143  frm_pos_map_t posMap;
144  p->QueryPositionMap(posMap, MARK_GOP_BYFRAME);
145  if (posMap.isEmpty())
146  p->QueryPositionMap(posMap, MARK_GOP_START);
147  if (posMap.isEmpty())
148  p->QueryPositionMap(posMap, MARK_KEYFRAME);
149 
150  if (posMap.isEmpty())
151  {
152  std::cout << "No seektable found" << std::endl;
153 
154  noSeektableRecordings.push_back(p);
155 
156  if (foundFile && fixSeektable)
157  {
158  QString command = GetAppBinDir() + "mythcommflag " +
159  QString("--rebuild --chanid %1 --starttime %2")
160  .arg(p->GetChanID())
161  .arg(p->GetRecordingStartTime(MythDate::ISODate));
162  std::cout << "Running - " << qPrintable(command) << std::endl;
163  QScopedPointer<MythSystem> cmd(MythSystem::Create(command));
164  cmd->Wait(0);
165  if (cmd.data()->GetExitCode() != GENERIC_EXIT_OK)
166  {
167  std::cout << "ERROR - mythcommflag exited with result: " << cmd.data()->GetExitCode() << std::endl;
168  }
169  }
170  }
171 
172  std::cout << "-------------------------------------------------------------------" << std::endl;
173  }
174  }
175 
176  if (!missingRecordings.empty())
177  {
178  std::cout << std::endl << std::endl;
179  std::cout << "MISSING RECORDINGS" << std::endl;
180  std::cout << "------------------" << std::endl;
181  for (auto *p : missingRecordings)
182  {
183  std::cout << qPrintable(CreateProgramInfoString(*p)) << std::endl;
184  std::cout << qPrintable(p->GetPlaybackURL()) << std::endl;
185  std::cout << "-------------------------------------------------------------------" << std::endl;
186  }
187  }
188 
189  if (!zeroByteRecordings.empty())
190  {
191  std::cout << std::endl << std::endl;
192  std::cout << "ZERO BYTE RECORDINGS" << std::endl;
193  std::cout << "--------------------" << std::endl;
194  for (auto *p : zeroByteRecordings)
195  {
196  std::cout << qPrintable(CreateProgramInfoString(*p)) << std::endl;
197  std::cout << qPrintable(p->GetPlaybackURL()) << std::endl;
198  std::cout << "-------------------------------------------------------------------" << std::endl;
199  }
200  }
201 
202  if (!noSeektableRecordings.empty())
203  {
204  std::cout << std::endl << std::endl;
205  std::cout << "NO SEEKTABLE RECORDINGS" << std::endl;
206  std::cout << "-----------------------" << std::endl;
207  for (auto *p : noSeektableRecordings)
208  {
209  std::cout << qPrintable(CreateProgramInfoString(*p)) << std::endl;
210  std::cout << qPrintable(p->GetPlaybackURL()) << std::endl;
211  std::cout << "File size is " << qPrintable(formatSize(p->GetFilesize(), 2)) << std::endl;
212  std::cout << "-------------------------------------------------------------------" << std::endl;
213  }
214  }
215 
216  std::cout << std::endl << std::endl << "SUMMARY" << std::endl;
217  std::cout << "Recordings : " << recordingList->size() << std::endl;
218  std::cout << "Missing Recordings : " << missingRecordings.size() << std::endl;
219  std::cout << "Zero byte Recordings : " << zeroByteRecordings.size() << std::endl;
220  std::cout << "Missing Seektables : " << noSeektableRecordings.size() << std::endl;
221 
222  return GENERIC_EXIT_OK;
223 }
224 
226 {
227  utilMap["checkrecordings"] = &CheckRecordings;
228 }
229 
230 /* vim: set expandtab tabstop=4 shiftwidth=4: */
MARK_KEYFRAME
@ MARK_KEYFRAME
Definition: programtypes.h:62
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:80
GENERIC_EXIT_OK
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
RemoteFile::GetFileSize
long long GetFileSize(void) const
GetFileSize: returns the remote file's size at the time it was first opened Will query the server in ...
Definition: remotefile.cpp:1091
RemoteFile::Exists
static bool Exists(const QString &url, struct stat *fileinfo)
Definition: remotefile.cpp:461
title
QString title
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:636
RemoteFile
Definition: remotefile.h:18
mythdirs.h
ProgramInfo::GetRecordingEndTime
QDateTime GetRecordingEndTime(void) const
Approximate time the recording should have ended, did end, or is intended to end.
Definition: programinfo.h:410
MythUtilCommandLineParser
Definition: mythutil/commandlineparser.h:9
remoteutil.h
ProgramInfo::GetRecordingStartTime
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:402
mythsystem.h
mythlogging.h
remotefile.h
hardwareprofile.config.p
p
Definition: config.py:33
MARK_GOP_START
@ MARK_GOP_START
Definition: programtypes.h:61
RemoteGetRecordedList
vector< ProgramInfo * > * RemoteGetRecordedList(int sort)
Definition: remoteutil.cpp:16
ProgramInfo::GetTitle
QString GetTitle(void) const
Definition: programinfo.h:359
frm_pos_map_t
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.
Definition: programtypes.h:46
MythDate::kSimplify
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
Definition: mythdate.h:23
CreateProgramInfoString
static QString CreateProgramInfoString(const ProgramInfo &pginfo)
Definition: recordingutils.cpp:43
cmdline
MythCommFlagCommandLineParser cmdline
Definition: mythtv/programs/mythcommflag/main.cpp:76
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:68
UtilMap
QMap< QString, UtilFunc > UtilMap
Definition: mythutil.h:15
GENERIC_EXIT_NOT_OK
#define GENERIC_EXIT_NOT_OK
Exited with error.
Definition: exitcodes.h:11
MythCommandLineParser::toBool
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
Definition: mythcommandlineparser.cpp:1943
MARK_GOP_BYFRAME
@ MARK_GOP_BYFRAME
Definition: programtypes.h:64
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:14
GetAppBinDir
QString GetAppBinDir(void)
Definition: mythdirs.cpp:221
recordingutils.h
formatSize
static QString formatSize(int64_t sizeKB, int prec)
Definition: recordingutils.cpp:22
MythDate::kDateTimeFull
@ kDateTimeFull
Default local time.
Definition: mythdate.h:20
MythDate::kTime
@ kTime
Default local time.
Definition: mythdate.h:19
exitcodes.h
CheckRecordings
static int CheckRecordings(const MythUtilCommandLineParser &cmdline)
Definition: recordingutils.cpp:68
registerRecordingUtils
void registerRecordingUtils(UtilMap &utilMap)
Definition: recordingutils.cpp:225
MythSystem::Create
static MythSystem * Create(const QStringList &args, uint flags=kMSNone, const QString &startPath=QString(), Priority cpuPriority=kInheritPriority, Priority diskPriority=kInheritPriority)
Definition: mythsystem.cpp:201
ProgramInfo::GetSubtitle
QString GetSubtitle(void) const
Definition: programinfo.h:361