MythTV  master
mythpreviewgen.cpp
Go to the documentation of this file.
1 // C++ headers
2 #include <cerrno>
3 #include <csignal>
4 #include <cstdlib>
5 #include <fcntl.h>
6 #include <fstream>
7 #include <iostream>
8 #include <libgen.h>
9 #include <sys/stat.h>
10 #include <sys/time.h> // for setpriority
11 #include <sys/types.h>
12 #include <unistd.h>
13 
14 // Qt
15 #include <QtGlobal>
16 #ifndef _WIN32
17 #include <QCoreApplication>
18 #else
19 #include <QApplication>
20 #endif
21 #include <QDir>
22 #include <QFile>
23 #include <QFileInfo>
24 #include <QMap>
25 
26 // MythTV
27 #include "libmyth/mythcontext.h"
28 #include "libmythbase/compat.h"
29 #include "libmythbase/exitcodes.h"
31 #include "libmythbase/mythdb.h"
33 #include "libmythbase/mythversion.h"
36 #include "libmythtv/dbcheck.h"
39 
40 //MythPreviewGen
42 
43 #define LOC QString("MythPreviewGen: ")
44 #define LOC_WARN QString("MythPreviewGen, Warning: ")
45 #define LOC_ERR QString("MythPreviewGen, Error: ")
46 
47 #ifdef Q_OS_MACOS
48 // 10.6 uses some file handles for its new Grand Central Dispatch thingy
49 static constexpr long UNUSED_FILENO { 5 };
50 #else
51 static constexpr long UNUSED_FILENO { 3 };
52 #endif
53 
54 int preview_helper(uint chanid, QDateTime starttime,
55  long long previewFrameNumber, std::chrono::seconds previewSeconds,
56  const QSize previewSize,
57  const QString &infile, const QString &outfile)
58 {
59  // Lower scheduling priority, to avoid problems with recordings.
60  if (setpriority(PRIO_PROCESS, 0, 9))
61  LOG(VB_GENERAL, LOG_ERR, "Setting priority failed." + ENO);
62 
63  if (!QFileInfo(infile).isReadable() && ((chanid == 0U) || !starttime.isValid()))
64  ProgramInfo::QueryKeyFromPathname(infile, chanid, starttime);
65 
66  ProgramInfo *pginfo = nullptr;
67  if (chanid && starttime.isValid())
68  {
69  pginfo = new ProgramInfo(chanid, starttime);
70  if (!pginfo->GetChanID())
71  {
72  LOG(VB_GENERAL, LOG_ERR,
73  QString("Cannot locate recording made on '%1' at '%2'")
74  .arg(chanid).arg(starttime.toString(Qt::ISODate)));
75  delete pginfo;
76  return GENERIC_EXIT_NOT_OK;
77  }
78  pginfo->SetPathname(pginfo->GetPlaybackURL(false, true));
79  }
80  else if (!infile.isEmpty())
81  {
82  if (!QFileInfo(infile).isReadable())
83  {
84  LOG(VB_GENERAL, LOG_ERR,
85  QString("Cannot read this file '%1'").arg(infile));
86  return GENERIC_EXIT_NOT_OK;
87  }
88  pginfo = new ProgramInfo(
89  infile, ""/*plot*/, ""/*title*/, ""/*sortTitle*/, ""/*subtitle*/,
90  ""/*sortSubtitle*/, ""/*director*/, 0/*season*/, 0/*episode*/,
91  ""/*inetref*/, 120min/*length_in_minutes*/, 1895/*year*/, ""/*id*/);
92  }
93  else
94  {
95  LOG(VB_GENERAL, LOG_ERR, "Cannot locate recording to preview");
96  return GENERIC_EXIT_NOT_OK;
97  }
98 
99  auto *previewgen = new PreviewGenerator(pginfo, QString(),
101 
102  if (previewFrameNumber >= 0)
103  previewgen->SetPreviewTimeAsFrameNumber(previewFrameNumber);
104 
105  if (previewSeconds >= 0s)
106  previewgen->SetPreviewTimeAsSeconds(previewSeconds);
107 
108  previewgen->SetOutputSize(previewSize);
109  previewgen->SetOutputFilename(outfile);
110  bool ok = previewgen->RunReal();
111  previewgen->deleteLater();
112 
113  delete pginfo;
114 
115  return (ok) ? GENERIC_EXIT_OK : GENERIC_EXIT_NOT_OK;
116 }
117 
118 int main(int argc, char **argv)
119 {
121  if (!cmdline.Parse(argc, argv))
122  {
123  cmdline.PrintHelp();
125  }
126 
127  if (cmdline.toBool("showhelp"))
128  {
129  cmdline.PrintHelp();
130  return GENERIC_EXIT_OK;
131  }
132 
133  if (cmdline.toBool("showversion"))
134  {
136  return GENERIC_EXIT_OK;
137  }
138 
139 #ifndef _WIN32
140 #if HAVE_CLOSE_RANGE
141  close_range(UNUSED_FILENO, sysconf(_SC_OPEN_MAX) - 1, 0);
142 #else
143  for (long i = UNUSED_FILENO; i < sysconf(_SC_OPEN_MAX) - 1; ++i)
144  close(i);
145 #endif
146  QCoreApplication a(argc, argv);
147 #else
148  // MINGW application needs a window to receive messages
149  // such as socket notifications :[
150  QApplication a(argc, argv);
151 #endif
152  QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHPREVIEWGEN);
153 
154  int retval = cmdline.ConfigureLogging();
155  if (retval != GENERIC_EXIT_OK)
156  return retval;
157 
158  if ((!cmdline.toBool("chanid") || !cmdline.toBool("starttime")) &&
159  !cmdline.toBool("inputfile"))
160  {
161  std::cerr << "--generate-preview must be accompanied by either " <<std::endl
162  << "\nboth --chanid and --starttime parameters, " << std::endl
163  << "\nor the --infile parameter." << std::endl;
165  }
166 
168 
169  // Don't listen to console input
170  close(0);
171 
172  if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
173  LOG(VB_GENERAL, LOG_WARNING, LOC + "Unable to ignore SIGPIPE");
174 
175  MythContext context {MYTH_BINARY_VERSION};
176  if (!context.Init(false))
177  {
178  LOG(VB_GENERAL, LOG_ERR, "Failed to init MythContext.");
180  }
181 
182  int ret = preview_helper(
183  cmdline.toUInt("chanid"), cmdline.toDateTime("starttime"),
184  cmdline.toLongLong("frame"), std::chrono::seconds(cmdline.toLongLong("seconds")),
185  cmdline.toSize("size"),
186  cmdline.toString("inputfile"), cmdline.toString("outputfile"));
187  return ret;
188 }
189 
190 /* vim: set expandtab tabstop=4 shiftwidth=4: */
ENO
#define ENO
This can be appended to the LOG args with "+".
Definition: mythlogging.h:74
mythdb.h
cmdline
MythCommFlagCommandLineParser cmdline
Definition: mythcommflag.cpp:63
UNUSED_FILENO
static constexpr long UNUSED_FILENO
Definition: mythpreviewgen.cpp:49
MythContext
Startup context for MythTV.
Definition: mythcontext.h:19
PreviewGenerator
This class creates a preview image of a recording.
Definition: previewgenerator.h:27
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
mythsystemevent.h
close
#define close
Definition: compat.h:43
PreviewGenerator::kLocal
@ kLocal
Definition: previewgenerator.h:43
MythCommandLineParser::Parse
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
Definition: mythcommandlineparser.cpp:1558
ProgramInfo::SetPathname
void SetPathname(const QString &pn)
Definition: programinfo.cpp:2459
programinfo.h
GENERIC_EXIT_INVALID_CMDLINE
@ GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:18
mythlogging.h
preview_helper
int preview_helper(uint chanid, QDateTime starttime, long long previewFrameNumber, std::chrono::seconds previewSeconds, const QSize previewSize, const QString &infile, const QString &outfile)
Definition: mythpreviewgen.cpp:54
dbcheck.h
main
int main(int argc, char **argv)
Definition: mythpreviewgen.cpp:118
MythPreviewGeneratorCommandLineParser
Definition: mythpreviewgen_commandlineparser.h:6
GENERIC_EXIT_OK
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:13
compat.h
SIGPIPE
#define SIGPIPE
Definition: compat.h:139
MythCommandLineParser::PrintVersion
static void PrintVersion(void)
Print application version information.
Definition: mythcommandlineparser.cpp:1386
MythCommandLineParser::toUInt
uint toUInt(const QString &key) const
Returns stored QVariant as an unsigned integer, falling to default if not provided.
Definition: mythcommandlineparser.cpp:2252
mythpreviewgen_commandlineparser.h
storagegroup.h
MythCommandLineParser::PrintHelp
void PrintHelp(void) const
Print command line option help.
Definition: mythcommandlineparser.cpp:1402
MYTH_APPNAME_MYTHPREVIEWGEN
static constexpr const char * MYTH_APPNAME_MYTHPREVIEWGEN
Definition: mythappname.h:11
mythappname.h
ProgramInfo::GetChanID
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:373
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
MythCommandLineParser::toString
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
Definition: mythcommandlineparser.cpp:2360
MythCommandLineParser::toBool
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
Definition: mythcommandlineparser.cpp:2203
MythCommandLineParser::toLongLong
long long toLongLong(const QString &key) const
Returns stored QVariant as a long integer, falling to default if not provided.
Definition: mythcommandlineparser.cpp:2279
setpriority
#define setpriority(x, y, z)
Definition: compat.h:130
ProgramInfo::GetPlaybackURL
QString GetPlaybackURL(bool checkMaster=false, bool forceCheckLocal=false)
Returns filename or URL to be used to play back this recording.
Definition: programinfo.cpp:2567
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:17
mythcontext.h
GENERIC_EXIT_NOT_OK
@ GENERIC_EXIT_NOT_OK
Exited with error.
Definition: exitcodes.h:14
MythCommandLineParser::toSize
QSize toSize(const QString &key) const
Returns stored QVariant as a QSize value, falling to default if not provided.
Definition: mythcommandlineparser.cpp:2333
MythCommandLineParser::ConfigureLogging
int ConfigureLogging(const QString &mask="general", bool progress=false)
Read in logging options and initialize the logging interface.
Definition: mythcommandlineparser.cpp:2876
PRIO_PROCESS
#define PRIO_PROCESS
Definition: compat.h:129
previewgenerator.h
exitcodes.h
MythCommandLineParser::toDateTime
QDateTime toDateTime(const QString &key) const
Returns stored QVariant as a QDateTime, falling to default if not provided.
Definition: mythcommandlineparser.cpp:2459
GENERIC_EXIT_NO_MYTHCONTEXT
@ GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
Definition: exitcodes.h:16
uint
unsigned int uint
Definition: freesurround.h:24
LOC
#define LOC
Definition: mythpreviewgen.cpp:43
ProgramInfo::QueryKeyFromPathname
static bool QueryKeyFromPathname(const QString &pathname, uint &chanid, QDateTime &recstartts)
Definition: programinfo.cpp:1219