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