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