MythTV  master
markuputils.cpp
Go to the documentation of this file.
1 
2 // C++ includes
3 #include <iostream> // for cout
4 using std::cout;
5 
6 // QT
7 #include <QFile>
8 #include <QTextStream>
9 #include <QVector>
10 #include <QDomDocument>
11 
12 // libmyth* includes
13 #include "libmythbase/exitcodes.h"
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: */
MARK_KEYFRAME
@ MARK_KEYFRAME
Definition: programtypes.h:62
MARK_COMM_END
@ MARK_COMM_END
Definition: programtypes.h:60
registerMarkupUtils
void registerMarkupUtils(UtilMap &utilMap)
Definition: markuputils.cpp:366
cmdline
MythCommFlagCommandLineParser cmdline
Definition: mythcommflag.cpp:72
SetMarkupList
static int SetMarkupList(const MythUtilCommandLineParser &cmdline, const QString &type, QString newList)
Definition: markuputils.cpp:72
GetCutList
static int GetCutList(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:122
MARK_CUT_END
@ MARK_CUT_END
Definition: programtypes.h:55
ProgramInfo::QueryMarkup
void QueryMarkup(QVector< MarkupEntry > &mapMark, QVector< MarkupEntry > &mapSeek) const
Definition: programinfo.cpp:4642
markuputils.h
frm_dir_map_t
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
Definition: programtypes.h:118
ClearSkipList
static int ClearSkipList(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:174
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MARK_UTIL_PROGSTART
@ MARK_UTIL_PROGSTART
Definition: programtypes.h:76
GENERIC_EXIT_OK
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:11
MythUtilCommandLineParser
Definition: mythutil_commandlineparser.h:8
GetProgramInfo
bool GetProgramInfo(const MythUtilCommandLineParser &cmdline, ProgramInfo &pginfo)
Definition: mythutil.cpp:32
ClearBookmarks
static int ClearBookmarks(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:201
ProgramInfo::GetPathname
QString GetPathname(void) const
Definition: programinfo.h:343
ProgramInfo::SaveCommBreakList
void SaveCommBreakList(frm_dir_map_t &frames) const
Definition: programinfo.cpp:3543
ProgramInfo::GetScheduledStartTime
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
Definition: programinfo.h:390
mythlogging.h
GetMarkup
static int GetMarkup(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:220
MARK_DURATION_MS
@ MARK_DURATION_MS
Definition: programtypes.h:74
MARK_GOP_START
@ MARK_GOP_START
Definition: programtypes.h:61
SetSkipList
static int SetSkipList(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:168
SetMarkup
static int SetMarkup(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:278
ProgramInfo::QueryCutList
bool QueryCutList(frm_dir_map_t &delMap, bool loadAutosave=false) const
Definition: programinfo.cpp:3464
SetCutList
static int SetCutList(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:127
MARK_BOOKMARK
@ MARK_BOOKMARK
Definition: programtypes.h:57
GENERIC_EXIT_NO_RECORDING_DATA
@ GENERIC_EXIT_NO_RECORDING_DATA
No program/recording data.
Definition: exitcodes.h:30
ProgramInfo::ClearMarkupFlag
void ClearMarkupFlag(MarkTypes type) const
Definition: programinfo.h:647
ProgramInfo::MarkupEntry
Definition: programinfo.h:692
ClearCutList
static int ClearCutList(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:133
MARK_TOTAL_FRAMES
@ MARK_TOTAL_FRAMES
Definition: programtypes.h:75
MARK_CUT_START
@ MARK_CUT_START
Definition: programtypes.h:56
ProgramInfo::GetChanID
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:372
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
UtilMap
QMap< QString, UtilFunc > UtilMap
Definition: mythutil.h:15
MARK_UTIL_LASTPLAYPOS
@ MARK_UTIL_LASTPLAYPOS
Definition: programtypes.h:77
MythCommandLineParser::toString
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
Definition: mythcommandlineparser.cpp:2344
ProgramInfo::QueryLastFrameInPosMap
uint64_t QueryLastFrameInPosMap(void) const
Returns last frame in position map or 0.
Definition: programinfo.cpp:1893
MARK_GOP_BYFRAME
@ MARK_GOP_BYFRAME
Definition: programtypes.h:64
ProgramInfo::ClearPositionMap
void ClearPositionMap(MarkTypes type) const
Definition: programinfo.cpp:3808
ProgramInfo::IsVideo
bool IsVideo(void) const
Definition: programinfo.h:485
ProgramInfo::SaveCutList
void SaveCutList(frm_dir_map_t &delMap, bool isAutoSave=false) const
Definition: programinfo.cpp:3496
ClearSeekTable
static int ClearSeekTable(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:179
ProgramInfo::QueryCommBreakList
void QueryCommBreakList(frm_dir_map_t &frames) const
Definition: programinfo.cpp:3550
ProgramInfo::SaveMarkup
void SaveMarkup(const QVector< MarkupEntry > &mapMark, const QVector< MarkupEntry > &mapSeek) const
Definition: programinfo.cpp:4723
CopySkipListToCutList
static int CopySkipListToCutList(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:138
exitcodes.h
build_compdb.filename
filename
Definition: build_compdb.py:21
GENERIC_EXIT_INVALID_CMDLINE
@ GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:16
MARK_COMM_START
@ MARK_COMM_START
Definition: programtypes.h:59
GetMarkupList
static int GetMarkupList(const MythUtilCommandLineParser &cmdline, const QString &type)
Definition: markuputils.cpp:19
GetSkipList
static int GetSkipList(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:163