MythTV master
markuputils.cpp
Go to the documentation of this file.
1
2// C++ includes
3#include <iostream> // for cout
4using std::cout;
5
6// QT
7#include <QFile>
8#include <QTextStream>
9#include <QVector>
10#include <QDomDocument>
11
12// libmyth* includes
15
16// Local includes
17#include "markuputils.h"
18
20 const QString &type)
21{
22 ProgramInfo pginfo;
23 if (!GetProgramInfo(cmdline, pginfo))
25
26 frm_dir_map_t cutlist;
27 frm_dir_map_t::const_iterator it;
28 QString result;
29
30 if (type == "cutlist")
31 pginfo.QueryCutList(cutlist);
32 else
33 pginfo.QueryCommBreakList(cutlist);
34
35 uint64_t lastStart = 0;
36 for (it = cutlist.cbegin(); it != cutlist.cend(); ++it)
37 {
38 if ((*it == MARK_COMM_START) ||
39 (*it == MARK_CUT_START))
40 {
41 if (!result.isEmpty())
42 result += ",";
43 lastStart = it.key();
44 result += QString("%1-").arg(lastStart);
45 }
46 else
47 {
48 if (result.isEmpty())
49 result += "0-";
50 result += QString("%1").arg(it.key());
51 }
52 }
53
54 if (result.endsWith('-'))
55 {
56 uint64_t lastFrame = pginfo.QueryLastFrameInPosMap() + 60;
57 if (lastFrame > lastStart)
58 result += QString("%1").arg(lastFrame);
59 }
60
61 if (type == "cutlist")
62 cout << QString("Cutlist: %1\n").arg(result).toLocal8Bit().constData();
63 else
64 {
65 cout << QString("Commercial Skip List: %1\n")
66 .arg(result).toLocal8Bit().constData();
67 }
68
69 return GENERIC_EXIT_OK;
70}
71
73 const QString &type, QString newList)
74{
75 ProgramInfo pginfo;
76 if (!GetProgramInfo(cmdline, pginfo))
78
79 bool isCutlist = (type == "cutlist");
80 frm_dir_map_t markuplist;
81
82 newList.remove(" ");
83
84 QStringList tokens = newList.split(",", Qt::SkipEmptyParts);
85
86 if (newList.isEmpty())
87 newList = "(EMPTY)";
88
89 for (const QString& token : std::as_const(tokens))
90 {
91 QStringList cutpair = token.split("-", Qt::SkipEmptyParts);
92 if (isCutlist)
93 {
94 markuplist[cutpair[0].toInt()] = MARK_CUT_START;
95 markuplist[cutpair[1].toInt()] = MARK_CUT_END;
96 }
97 else
98 {
99 markuplist[cutpair[0].toInt()] = MARK_COMM_START;
100 markuplist[cutpair[1].toInt()] = MARK_COMM_END;
101 }
102 }
103
104 if (isCutlist)
105 {
106 pginfo.SaveCutList(markuplist);
107 cout << QString("Cutlist set to: %1\n")
108 .arg(newList).toLocal8Bit().constData();
109 LOG(VB_GENERAL, LOG_NOTICE, QString("Cutlist set to: %1").arg(newList));
110 }
111 else
112 {
113 pginfo.SaveCommBreakList(markuplist);
114 cout << QString("Commercial Skip List set to: %1\n")
115 .arg(newList).toLocal8Bit().constData();
116 LOG(VB_GENERAL, LOG_NOTICE, QString("Commercial Skip List set to: %1").arg(newList));
117 }
118
119 return GENERIC_EXIT_OK;
120}
121
123{
124 return GetMarkupList(cmdline, "cutlist");
125}
126
128{
129 return SetMarkupList(cmdline, QString("cutlist"),
130 cmdline.toString("setcutlist"));
131}
132
134{
135 return SetMarkupList(cmdline, QString("cutlist"), QString(""));
136}
137
139{
140 ProgramInfo pginfo;
141 if (!GetProgramInfo(cmdline, pginfo))
143
144 frm_dir_map_t cutlist;
145 frm_dir_map_t::const_iterator it;
146
147 pginfo.QueryCommBreakList(cutlist);
148 for (it = cutlist.cbegin(); it != cutlist.cend(); ++it)
149 {
150 if (*it == MARK_COMM_START)
151 cutlist[it.key()] = MARK_CUT_START;
152 else
153 cutlist[it.key()] = MARK_CUT_END;
154 }
155 pginfo.SaveCutList(cutlist);
156
157 cout << "Commercial Skip List copied to Cutlist\n";
158 LOG(VB_GENERAL, LOG_NOTICE, "Commercial Skip List copied to Cutlist");
159
160 return GENERIC_EXIT_OK;
161}
162
164{
165 return GetMarkupList(cmdline, "skiplist");
166}
167
169{
170 return SetMarkupList(cmdline, QString("skiplist"),
171 cmdline.toString("setskiplist"));
172}
173
175{
176 return SetMarkupList(cmdline, QString("skiplist"), QString(""));
177}
178
180{
181 ProgramInfo pginfo;
182 if (!GetProgramInfo(cmdline, pginfo))
184
185 cout << "Clearing Seek Table\n";
186 LOG(VB_GENERAL, LOG_NOTICE, pginfo.IsVideo() ?
187 QString("Clearing Seek Table for Video %1").arg(pginfo.GetPathname()) :
188 QString("Clearing Seek Table for Channel ID %1 @ %2")
189 .arg(pginfo.GetChanID())
190 .arg(pginfo.GetScheduledStartTime().toString()));
197
198 return GENERIC_EXIT_OK;
199}
200
202{
203 ProgramInfo pginfo;
204 if (!GetProgramInfo(cmdline, pginfo))
206
207 cout << "Clearing bookmarks\n";
208 LOG(VB_GENERAL, LOG_NOTICE, pginfo.IsVideo() ?
209 QString("Clearing bookmarks for video %1").arg(pginfo.GetPathname()) :
210 QString("Clearing bookmarks for channel id %1 @ %2")
211 .arg(pginfo.GetChanID())
212 .arg(pginfo.GetScheduledStartTime().toString()));
216
217 return GENERIC_EXIT_OK;
218}
219
221{
222 ProgramInfo pginfo;
223 if (!GetProgramInfo(cmdline, pginfo))
225
226 QString filename = cmdline.toString("getmarkup");
227 if (filename.isEmpty())
228 {
229 LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --getmarkup filename\n");
231 }
232 QVector<ProgramInfo::MarkupEntry> mapMark;
233 QVector<ProgramInfo::MarkupEntry> mapSeek;
234 pginfo.QueryMarkup(mapMark, mapSeek);
235 QFile outfile(filename);
236 if (!outfile.open(QIODevice::WriteOnly))
237 {
238 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
239 QString("Couldn't open output file %1\n").arg(filename));
241 }
242 QTextStream stream(&outfile);
243 QDomDocument xml;
244 QDomProcessingInstruction processing =
245 xml.createProcessingInstruction("xml",
246 "version='1.0' encoding='utf-8'");
247 xml.appendChild(processing);
248 QDomElement root = xml.createElement("metadata");
249 xml.appendChild(root);
250 QDomElement item = xml.createElement("item");
251 root.appendChild(item);
252 QDomElement markup = xml.createElement("markup");
253 item.appendChild(markup);
254 for (const auto & entry : std::as_const(mapMark))
255 {
256 QDomElement child = xml.createElement("mark");
257 child.setAttribute("type", entry.type);
258 child.setAttribute("frame", (qulonglong)entry.frame);
259 if (!entry.isDataNull)
260 child.setAttribute("data", (qulonglong)entry.data);
261 markup.appendChild(child);
262 }
263 for (const auto & entry : std::as_const(mapSeek))
264 {
265 QDomElement child = xml.createElement("seek");
266 child.setAttribute("type", entry.type);
267 child.setAttribute("frame", (qulonglong)entry.frame);
268 if (!entry.isDataNull)
269 child.setAttribute("data", (qulonglong)entry.data);
270 markup.appendChild(child);
271 }
272
273 stream << xml.toString(2);
274 outfile.close();
275 return GENERIC_EXIT_OK;
276}
277
279{
280 ProgramInfo pginfo;
281 if (!GetProgramInfo(cmdline, pginfo))
283
284 QString filename = cmdline.toString("setmarkup");
285 if (filename.isEmpty())
286 {
287 LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --setmarkup filename\n");
289 }
290 QVector<ProgramInfo::MarkupEntry> mapMark;
291 QVector<ProgramInfo::MarkupEntry> mapSeek;
292 QFile infile(filename);
293 if (!infile.open(QIODevice::ReadOnly))
294 {
295 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
296 QString("Couldn't open input file %1\n").arg(filename));
298 }
299 QDomDocument xml;
300 if (!xml.setContent(&infile))
301 {
302 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
303 QString("Failed to read valid XML from file %1\n").arg(filename));
305 }
306 QDomElement metadata = xml.documentElement();
307 if (metadata.tagName() != "metadata")
308 {
309 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
310 QString("Expected top-level 'metadata' element "
311 "in file %1\n").arg(filename));
313 }
314 QDomNode item = metadata.firstChild();
315 if (!item.isElement() || item.toElement().tagName() != "item")
316 {
317 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
318 QString("Expected 'item' element within 'metadata' element "
319 "in file %1\n").arg(filename));
321 }
322 QDomNode markup = item.firstChild();
323 if (!markup.isElement() || markup.toElement().tagName() != "markup")
324 {
325 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
326 QString("Expected 'markup' element within 'item' element "
327 "in file %1\n").arg(filename));
329 }
330 for (QDomNode n = markup.firstChild(); !n.isNull(); n = n.nextSibling())
331 {
332 if (n.isElement())
333 {
334 QDomElement e = n.toElement();
335 QString tagName = e.tagName();
336 bool isMark = false;
337 if (tagName == "mark")
338 isMark = true;
339 else if (tagName == "seek")
340 isMark = false;
341 else
342 {
343 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
344 QString("Weird tag '%1', expected 'mark' or 'seek'\n")
345 .arg(tagName));
346 continue;
347 }
348 int type = e.attribute("type").toInt();
349 uint64_t frame = e.attribute("frame").toULongLong();
350 QString dataString = e.attribute("data");
351 uint64_t data = dataString.toULongLong();
352 bool isDataNull = dataString.isNull();
353 ProgramInfo::MarkupEntry entry(type, frame,
354 data, isDataNull);
355 if (isMark)
356 mapMark.append(entry);
357 else
358 mapSeek.append(entry);
359 }
360 }
361 pginfo.SaveMarkup(mapMark, mapSeek);
362
363 return GENERIC_EXIT_OK;
364}
365
367{
368 utilMap["gencutlist"] = &CopySkipListToCutList;
369 utilMap["getcutlist"] = &GetCutList;
370 utilMap["setcutlist"] = &SetCutList;
371 utilMap["clearcutlist"] = &ClearCutList;
372 utilMap["getskiplist"] = &GetSkipList;
373 utilMap["setskiplist"] = &SetSkipList;
374 utilMap["clearskiplist"] = &ClearSkipList;
375 utilMap["clearseektable"] = &ClearSeekTable;
376 utilMap["clearbookmarks"] = &ClearBookmarks;
377 utilMap["getmarkup"] = &GetMarkup;
378 utilMap["setmarkup"] = &SetMarkup;
379}
380
381/* vim: set expandtab tabstop=4 shiftwidth=4: */
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
Holds information on recordings and videos.
Definition: programinfo.h:68
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:373
void QueryMarkup(QVector< MarkupEntry > &mapMark, QVector< MarkupEntry > &mapSeek) const
bool IsVideo(void) const
Definition: programinfo.h:490
void ClearMarkupFlag(MarkTypes type) const
Definition: programinfo.h:652
void ClearPositionMap(MarkTypes type) const
void SaveMarkup(const QVector< MarkupEntry > &mapMark, const QVector< MarkupEntry > &mapSeek) const
void QueryCommBreakList(frm_dir_map_t &frames) const
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
Definition: programinfo.h:391
uint64_t QueryLastFrameInPosMap(void) const
Returns last frame in position map or 0.
bool QueryCutList(frm_dir_map_t &delMap, bool loadAutosave=false) const
void SaveCommBreakList(frm_dir_map_t &frames) const
void SaveCutList(frm_dir_map_t &delMap, bool isAutoSave=false) const
QString GetPathname(void) const
Definition: programinfo.h:344
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:13
@ GENERIC_EXIT_NO_RECORDING_DATA
No program/recording data.
Definition: exitcodes.h:32
@ GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:18
static int SetSkipList(const MythUtilCommandLineParser &cmdline)
static int SetMarkupList(const MythUtilCommandLineParser &cmdline, const QString &type, QString newList)
Definition: markuputils.cpp:72
static int ClearBookmarks(const MythUtilCommandLineParser &cmdline)
static int CopySkipListToCutList(const MythUtilCommandLineParser &cmdline)
static int GetMarkup(const MythUtilCommandLineParser &cmdline)
static int GetMarkupList(const MythUtilCommandLineParser &cmdline, const QString &type)
Definition: markuputils.cpp:19
static int GetCutList(const MythUtilCommandLineParser &cmdline)
static int GetSkipList(const MythUtilCommandLineParser &cmdline)
static int SetMarkup(const MythUtilCommandLineParser &cmdline)
static int ClearSeekTable(const MythUtilCommandLineParser &cmdline)
static int ClearCutList(const MythUtilCommandLineParser &cmdline)
static int ClearSkipList(const MythUtilCommandLineParser &cmdline)
static int SetCutList(const MythUtilCommandLineParser &cmdline)
void registerMarkupUtils(UtilMap &utilMap)
MythCommFlagCommandLineParser cmdline
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
bool GetProgramInfo(const MythUtilCommandLineParser &cmdline, ProgramInfo &pginfo)
Definition: mythutil.cpp:32
QMap< QString, UtilFunc > UtilMap
Definition: mythutil.h:15
@ MARK_CUT_START
Definition: programtypes.h:55
@ MARK_KEYFRAME
Definition: programtypes.h:61
@ MARK_BOOKMARK
Definition: programtypes.h:56
@ MARK_UTIL_PROGSTART
Definition: programtypes.h:75
@ MARK_TOTAL_FRAMES
Definition: programtypes.h:74
@ MARK_GOP_BYFRAME
Definition: programtypes.h:63
@ MARK_CUT_END
Definition: programtypes.h:54
@ MARK_UTIL_LASTPLAYPOS
Definition: programtypes.h:76
@ MARK_COMM_END
Definition: programtypes.h:59
@ MARK_COMM_START
Definition: programtypes.h:58
@ MARK_DURATION_MS
Definition: programtypes.h:73
@ MARK_GOP_START
Definition: programtypes.h:60
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
Definition: programtypes.h:117