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 "exitcodes.h"
14 #include "mythlogging.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.replace(QRegExp(" "), "");
83 
84 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
85  QStringList tokens = newList.split(",", QString::SkipEmptyParts);
86 #else
87  QStringList tokens = newList.split(",", Qt::SkipEmptyParts);
88 #endif
89 
90  if (newList.isEmpty())
91  newList = "(EMPTY)";
92 
93  for (int i = 0; i < tokens.size(); i++)
94  {
95 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
96  QStringList cutpair = tokens[i].split("-", QString::SkipEmptyParts);
97 #else
98  QStringList cutpair = tokens[i].split("-", Qt::SkipEmptyParts);
99 #endif
100  if (isCutlist)
101  {
102  markuplist[cutpair[0].toInt()] = MARK_CUT_START;
103  markuplist[cutpair[1].toInt()] = MARK_CUT_END;
104  }
105  else
106  {
107  markuplist[cutpair[0].toInt()] = MARK_COMM_START;
108  markuplist[cutpair[1].toInt()] = MARK_COMM_END;
109  }
110  }
111 
112  if (isCutlist)
113  {
114  pginfo.SaveCutList(markuplist);
115  cout << QString("Cutlist set to: %1\n")
116  .arg(newList).toLocal8Bit().constData();
117  LOG(VB_GENERAL, LOG_NOTICE, QString("Cutlist set to: %1").arg(newList));
118  }
119  else
120  {
121  pginfo.SaveCommBreakList(markuplist);
122  cout << QString("Commercial Skip List set to: %1\n")
123  .arg(newList).toLocal8Bit().constData();
124  LOG(VB_GENERAL, LOG_NOTICE, QString("Commercial Skip List set to: %1").arg(newList));
125  }
126 
127  return GENERIC_EXIT_OK;
128 }
129 
131 {
132  return GetMarkupList(cmdline, "cutlist");
133 }
134 
136 {
137  return SetMarkupList(cmdline, QString("cutlist"),
138  cmdline.toString("setcutlist"));
139 }
140 
142 {
143  return SetMarkupList(cmdline, QString("cutlist"), QString(""));
144 }
145 
147 {
148  ProgramInfo pginfo;
149  if (!GetProgramInfo(cmdline, pginfo))
151 
152  frm_dir_map_t cutlist;
153  frm_dir_map_t::const_iterator it;
154 
155  pginfo.QueryCommBreakList(cutlist);
156  for (it = cutlist.cbegin(); it != cutlist.cend(); ++it)
157  {
158  if (*it == MARK_COMM_START)
159  cutlist[it.key()] = MARK_CUT_START;
160  else
161  cutlist[it.key()] = MARK_CUT_END;
162  }
163  pginfo.SaveCutList(cutlist);
164 
165  cout << "Commercial Skip List copied to Cutlist\n";
166  LOG(VB_GENERAL, LOG_NOTICE, "Commercial Skip List copied to Cutlist");
167 
168  return GENERIC_EXIT_OK;
169 }
170 
172 {
173  return GetMarkupList(cmdline, "skiplist");
174 }
175 
177 {
178  return SetMarkupList(cmdline, QString("skiplist"),
179  cmdline.toString("setskiplist"));
180 }
181 
183 {
184  return SetMarkupList(cmdline, QString("skiplist"), QString(""));
185 }
186 
188 {
189  ProgramInfo pginfo;
190  if (!GetProgramInfo(cmdline, pginfo))
192 
193  cout << "Clearing Seek Table\n";
194  LOG(VB_GENERAL, LOG_NOTICE, pginfo.IsVideo() ?
195  QString("Clearing Seek Table for Video %1").arg(pginfo.GetPathname()) :
196  QString("Clearing Seek Table for Channel ID %1 @ %2")
197  .arg(pginfo.GetChanID())
198  .arg(pginfo.GetScheduledStartTime().toString()));
205 
206  return GENERIC_EXIT_OK;
207 }
208 
210 {
211  ProgramInfo pginfo;
212  if (!GetProgramInfo(cmdline, pginfo))
214 
215  cout << "Clearing bookmarks\n";
216  LOG(VB_GENERAL, LOG_NOTICE, pginfo.IsVideo() ?
217  QString("Clearing bookmarks for video %1").arg(pginfo.GetPathname()) :
218  QString("Clearing bookmarks for channel id %1 @ %2")
219  .arg(pginfo.GetChanID())
220  .arg(pginfo.GetScheduledStartTime().toString()));
224 
225  return GENERIC_EXIT_OK;
226 }
227 
229 {
230  ProgramInfo pginfo;
231  if (!GetProgramInfo(cmdline, pginfo))
233 
234  QString filename = cmdline.toString("getmarkup");
235  if (filename.isEmpty())
236  {
237  LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --getmarkup filename\n");
239  }
240  QVector<ProgramInfo::MarkupEntry> mapMark;
241  QVector<ProgramInfo::MarkupEntry> mapSeek;
242  pginfo.QueryMarkup(mapMark, mapSeek);
243  QFile outfile(filename);
244  if (!outfile.open(QIODevice::WriteOnly))
245  {
246  LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
247  QString("Couldn't open output file %1\n").arg(filename));
249  }
250  QTextStream stream(&outfile);
251  QDomDocument xml;
252  QDomProcessingInstruction processing =
253  xml.createProcessingInstruction("xml",
254  "version='1.0' encoding='utf-8'");
255  xml.appendChild(processing);
256  QDomElement root = xml.createElement("metadata");
257  xml.appendChild(root);
258  QDomElement item = xml.createElement("item");
259  root.appendChild(item);
260  QDomElement markup = xml.createElement("markup");
261  item.appendChild(markup);
262  for (const auto & entry : qAsConst(mapMark))
263  {
264  QDomElement child = xml.createElement("mark");
265  child.setAttribute("type", entry.type);
266  child.setAttribute("frame", (qulonglong)entry.frame);
267  if (!entry.isDataNull)
268  child.setAttribute("data", (qulonglong)entry.data);
269  markup.appendChild(child);
270  }
271  for (const auto & entry : qAsConst(mapSeek))
272  {
273  QDomElement child = xml.createElement("seek");
274  child.setAttribute("type", entry.type);
275  child.setAttribute("frame", (qulonglong)entry.frame);
276  if (!entry.isDataNull)
277  child.setAttribute("data", (qulonglong)entry.data);
278  markup.appendChild(child);
279  }
280 
281  stream << xml.toString(2);
282  outfile.close();
283  return GENERIC_EXIT_OK;
284 }
285 
287 {
288  ProgramInfo pginfo;
289  if (!GetProgramInfo(cmdline, pginfo))
291 
292  QString filename = cmdline.toString("setmarkup");
293  if (filename.isEmpty())
294  {
295  LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --setmarkup filename\n");
297  }
298  QVector<ProgramInfo::MarkupEntry> mapMark;
299  QVector<ProgramInfo::MarkupEntry> mapSeek;
300  QFile infile(filename);
301  if (!infile.open(QIODevice::ReadOnly))
302  {
303  LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
304  QString("Couldn't open input file %1\n").arg(filename));
306  }
307  QDomDocument xml;
308  if (!xml.setContent(&infile))
309  {
310  LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
311  QString("Failed to read valid XML from file %1\n").arg(filename));
313  }
314  QDomElement metadata = xml.documentElement();
315  if (metadata.tagName() != "metadata")
316  {
317  LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
318  QString("Expected top-level 'metadata' element "
319  "in file %1\n").arg(filename));
321  }
322  QDomNode item = metadata.firstChild();
323  if (!item.isElement() || item.toElement().tagName() != "item")
324  {
325  LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
326  QString("Expected 'item' element within 'metadata' element "
327  "in file %1\n").arg(filename));
329  }
330  QDomNode markup = item.firstChild();
331  if (!markup.isElement() || markup.toElement().tagName() != "markup")
332  {
333  LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
334  QString("Expected 'markup' element within 'item' element "
335  "in file %1\n").arg(filename));
337  }
338  for (QDomNode n = markup.firstChild(); !n.isNull(); n = n.nextSibling())
339  {
340  if (n.isElement())
341  {
342  QDomElement e = n.toElement();
343  QString tagName = e.tagName();
344  bool isMark = false;
345  if (tagName == "mark")
346  isMark = true;
347  else if (tagName == "seek")
348  isMark = false;
349  else
350  {
351  LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
352  QString("Weird tag '%1', expected 'mark' or 'seek'\n")
353  .arg(tagName));
354  continue;
355  }
356  int type = e.attribute("type").toInt();
357  uint64_t frame = e.attribute("frame").toULongLong();
358  QString dataString = e.attribute("data");
359  uint64_t data = dataString.toULongLong();
360  bool isDataNull = dataString.isNull();
361  ProgramInfo::MarkupEntry entry(type, frame,
362  data, isDataNull);
363  if (isMark)
364  mapMark.append(entry);
365  else
366  mapSeek.append(entry);
367  }
368  }
369  pginfo.SaveMarkup(mapMark, mapSeek);
370 
371  return GENERIC_EXIT_OK;
372 }
373 
375 {
376  utilMap["gencutlist"] = &CopySkipListToCutList;
377  utilMap["getcutlist"] = &GetCutList;
378  utilMap["setcutlist"] = &SetCutList;
379  utilMap["clearcutlist"] = &ClearCutList;
380  utilMap["getskiplist"] = &GetSkipList;
381  utilMap["setskiplist"] = &SetSkipList;
382  utilMap["clearskiplist"] = &ClearSkipList;
383  utilMap["clearseektable"] = &ClearSeekTable;
384  utilMap["clearbookmarks"] = &ClearBookmarks;
385  utilMap["getmarkup"] = &GetMarkup;
386  utilMap["setmarkup"] = &SetMarkup;
387 }
388 
389 /* vim: set expandtab tabstop=4 shiftwidth=4: */
e
QDomElement e
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1423
MARK_KEYFRAME
@ MARK_KEYFRAME
Definition: programtypes.h:62
GENERIC_EXIT_OK
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
MARK_COMM_END
@ MARK_COMM_END
Definition: programtypes.h:60
root
QDomElement root
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:659
registerMarkupUtils
void registerMarkupUtils(UtilMap &utilMap)
Definition: markuputils.cpp:374
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:130
MARK_CUT_END
@ MARK_CUT_END
Definition: programtypes.h:55
ProgramInfo::QueryMarkup
void QueryMarkup(QVector< MarkupEntry > &mapMark, QVector< MarkupEntry > &mapSeek) const
Definition: programinfo.cpp:4380
arg
arg(title).arg(filename).arg(doDelete))
markuputils.h
frm_dir_map_t
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
Definition: programtypes.h:82
ClearSkipList
static int ClearSkipList(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:182
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MARK_UTIL_PROGSTART
@ MARK_UTIL_PROGSTART
Definition: programtypes.h:76
GENERIC_EXIT_INVALID_CMDLINE
#define GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:15
MythUtilCommandLineParser
Definition: mythutil/commandlineparser.h:9
GetProgramInfo
bool GetProgramInfo(const MythUtilCommandLineParser &cmdline, ProgramInfo &pginfo)
Definition: mythutil.cpp:11
ClearBookmarks
static int ClearBookmarks(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:209
ProgramInfo::GetPathname
QString GetPathname(void) const
Definition: programinfo.h:341
ProgramInfo::SaveCommBreakList
void SaveCommBreakList(frm_dir_map_t &frames) const
Definition: programinfo.cpp:3366
ProgramInfo::GetScheduledStartTime
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
Definition: programinfo.h:388
mythlogging.h
GetMarkup
static int GetMarkup(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:228
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:176
SetMarkup
static int SetMarkup(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:286
GENERIC_EXIT_NO_RECORDING_DATA
#define GENERIC_EXIT_NO_RECORDING_DATA
No program/recording data.
Definition: exitcodes.h:29
ProgramInfo::QueryCutList
bool QueryCutList(frm_dir_map_t &delMap, bool loadAutosave=false) const
Definition: programinfo.cpp:3287
SetCutList
static int SetCutList(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:135
MARK_BOOKMARK
@ MARK_BOOKMARK
Definition: programtypes.h:57
filename
QString filename
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:640
ProgramInfo::ClearMarkupFlag
void ClearMarkupFlag(MarkTypes type) const
Definition: programinfo.h:629
ProgramInfo::MarkupEntry
Definition: programinfo.h:675
ClearCutList
static int ClearCutList(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:141
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:370
cmdline
MythCommFlagCommandLineParser cmdline
Definition: mythtv/programs/mythcommflag/main.cpp:77
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:68
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:2101
ProgramInfo::QueryLastFrameInPosMap
uint64_t QueryLastFrameInPosMap(void) const
Returns last frame in position map or 0.
Definition: programinfo.cpp:1796
MARK_GOP_BYFRAME
@ MARK_GOP_BYFRAME
Definition: programtypes.h:64
ProgramInfo::ClearPositionMap
void ClearPositionMap(MarkTypes type) const
Definition: programinfo.cpp:3631
ProgramInfo::IsVideo
bool IsVideo(void) const
Definition: programinfo.h:482
ProgramInfo::SaveCutList
void SaveCutList(frm_dir_map_t &delMap, bool isAutoSave=false) const
Definition: programinfo.cpp:3319
ClearSeekTable
static int ClearSeekTable(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:187
ProgramInfo::QueryCommBreakList
void QueryCommBreakList(frm_dir_map_t &frames) const
Definition: programinfo.cpp:3373
ProgramInfo::SaveMarkup
void SaveMarkup(const QVector< MarkupEntry > &mapMark, const QVector< MarkupEntry > &mapSeek) const
Definition: programinfo.cpp:4461
CopySkipListToCutList
static int CopySkipListToCutList(const MythUtilCommandLineParser &cmdline)
Definition: markuputils.cpp:146
exitcodes.h
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:171