Go to the documentation of this file.
4 #include <QApplication>
5 #include <QImageReader>
28 (QEvent::Type) QEvent::registerEventType();
32 template <
typename DirListType>
37 const QStringList &image_extensions) :
38 m_videoFiles(video_files)
40 for (
const auto& ext : std::as_const(image_extensions))
41 m_imageExt.insert(ext.toLower());
45 [[maybe_unused]]
const QString &fq_dir_name)
override
50 void handleFile([[maybe_unused]]
const QString &file_name,
51 const QString &fq_file_name,
52 const QString &extension,
53 const QString &host)
override
57 LOG(VB_GENERAL, LOG_DEBUG,
58 QString(
"handleFile: %1 :: %2").arg(fq_file_name).arg(host));
60 if (m_imageExt.find(extension.toLower()) == m_imageExt.end())
62 m_videoFiles[fq_file_name].check =
false;
63 m_videoFiles[fq_file_name].host = host;
94 for (
const auto& host : std::as_const(hosts))
101 QStringList searchhosts;
105 QStringList::iterator iter = dirs.begin();
106 QStringList::iterator iter2;
107 while ( iter != dirs.end() )
109 if (iter->startsWith(
"myth://"))
112 QString host = sgurl.host().toLower();
113 QString path = sgurl.path();
121 iter = dirs.erase(iter);
124 if ((host == master) && (!mdirs.contains(path)))
130 else if (!searchhosts.contains(host))
134 searchhosts.append(host);
143 if ((!searchhosts.contains(*iter)) && (master != *iter))
145 for (iter2 = mdirs.begin(); iter2 != mdirs.end(); ++iter2)
150 0, *iter2,
"Videos"));
166 QList<QByteArray> image_types = QImageReader::supportedImageFormats();
167 QStringList imageExtensions;
168 for (
const auto & format : std::as_const(image_types))
169 imageExtensions.push_back(QString(format));
171 LOG(VB_GENERAL, LOG_INFO, QString(
"Beginning Video Scan."));
178 tr(
"Searching for video files"));
183 if (dir.startsWith(
"myth://"))
186 QString host = sgurl.host().toLower();
190 LOG(VB_GENERAL, LOG_ERR,
191 QString(
"Failed to scan :%1:").arg(dir));
204 QCoreApplication::postEvent(
m_parent,
211 slist << QString(
"added::%1").arg(
id);
213 slist << QString(
"moved::%1").arg(
id);
215 slist << QString(
"deleted::%1").arg(
id);
217 MythEvent me(
"VIDEO_LIST_CHANGE", slist);
231 [[maybe_unused]]
const QString &
filename)
248 FileCheckList::iterator iter;
252 tr(
"Verifying video files"));
257 QString lname =
file->GetFilename();
258 QString lhost =
file->GetHost().toLower();
259 if (!lname.isEmpty())
261 iter = files.find(lname);
262 if (iter != files.end())
264 if (lhost != iter->second.host)
268 remove.emplace_back(
file->GetID(), lname);
274 iter->second.check =
true;
277 else if (lhost.isEmpty())
281 remove.emplace_back(
file->GetID(), lname);
285 LOG(VB_GENERAL, LOG_INFO,
286 QString(
"Removing file SG(%1) :%2:")
288 remove.emplace_back(
file->GetID(), lname);
292 LOG(VB_GENERAL, LOG_WARNING,
293 QString(
"SG(%1) not available. Not removing file :%2:")
310 tr(
"Updating video database"));
312 for (
auto p = add.cbegin();
p != add.cend(); ++
p)
315 if (!
p->second.check)
321 if (hash !=
"NULL" && !hash.isEmpty())
328 LOG(VB_GENERAL, LOG_ERR,
329 QString(
"Hash %1 already exists in the "
330 "database, updating record %2 "
331 "with new filename %3")
332 .arg(hash).arg(
id).arg(
p->first));
339 p->first, QString(), hash,
345 QString(), QString(), QString(), QString(),
356 LOG(VB_GENERAL, LOG_INFO, QString(
"Adding : %1 : %2 : %3")
369 ret += remove.size();
370 for (
const auto & item : remove)
385 const QStringList &imageExtensions,
394 LOG(VB_GENERAL,LOG_INFO, QString(
"buildFileList directory = %1")
410 QApplication::postEvent(
m_dialog, pue);
434 "videoscanprogressdialog");
436 if (progressDlg->Create())
438 popupStack->
AddScreen(progressDlg,
false);
447 progressDlg =
nullptr;
455 LOG(VB_GENERAL, LOG_WARNING,
"Could not retrieve list of "
456 "available backends.");
472 if (!failedHosts.empty())
474 QString hosts = failedHosts.join(
" ");
475 QString msg = tr(
"Failed to Scan SG Video Hosts:\n\n%1\n\n"
476 "If they no longer exist please remove them")
void SendMessage(const QString &message)
void handleFile([[maybe_unused]] const QString &file_name, const QString &fq_file_name, const QString &extension, const QString &host) override
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
QString GetMasterHostName(void)
void SendProgressEvent(uint progress, uint total=0, QString messsage=QString())
DirListType & m_videoFiles
void getExtensionIgnoreList(ext_ignore_list &ext_ignore) const
void doScan(const QStringList &dirs)
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
This class is used as a container for messages.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
DirectoryHandler * newDir([[maybe_unused]] const QString &dir_name, [[maybe_unused]] const QString &fq_dir_name) override
QStringList GetOfflineSGHosts(void)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
bool buildFileList(const QString &directory, const QStringList &imageExtensions, FileCheckList &filelist) const
MythUIProgressDialog(QString message, MythScreenStack *parent, const char *name)
class VideoScannerThread * m_scanThread
static QString GenMythURL(const QString &host=QString(), int port=0, QString path=QString(), const QString &storageGroup=QString())
MythUIProgressDialog * m_dialog
QStringList GetVideoDirs()
void SendEvent(const MythEvent &event)
std::vector< std::pair< QString, bool > > ext_ignore_list
dirhandler(DirListType &video_files, const QStringList &image_extensions)
void SetDirs(QStringList dirs)
const QString VIDEO_COVERFILE_DEFAULT
const QString VIDEO_PLOT_DEFAULT
QStringList m_liveSGHosts
QThread * qthread(void)
Returns the thread, this will always return the same pointer no matter how often you restart the thre...
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
static const Type kEventType
const QString VIDEO_TRAILER_DEFAULT
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
VideoMetadataListManager * m_dbMetadata
const QString VIDEO_INETREF_DEFAULT
const QString VIDEO_FANART_DEFAULT
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
bool GetBoolSetting(const QString &key, bool defaultval=false)
static FileAssociations & getFileAssociation()
void SetProgressDialog(MythUIProgressDialog *dialog)
bool ScanVideoDirectory(const QString &start_path, DirectoryHandler *handler, const FileAssociations::ext_ignore_list &ext_disposition, bool list_unknown_extensions)
void run() override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
~VideoScannerThread() override
const QString VIDEO_RATING_DEFAULT
This is a wrapper around QThread that does several additional things.
VideoScannerThread(QObject *parent)
MythMainWindow * GetMythMainWindow(void)
bool isRunning(void) const
void verifyFiles(FileCheckList &files, PurgeList &remove)
void removeOrphans(unsigned int id, const QString &filename)
MythScreenStack * GetStack(const QString &Stackname)
bool updateDB(const FileCheckList &add, const PurgeList &remove)
QStringList m_offlineSGHosts
std::map< QString, CheckStruct > FileCheckList
const QString VIDEO_BANNER_DEFAULT
void SetHosts(const QStringList &hosts)
std::set< QString > image_ext
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
QStringList m_directories
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
bool getDataChanged() const
bool RemoteGetActiveBackends(QStringList *list)
return list of backends currently connected to the master
std::vector< std::pair< int, QString > > PurgeList
const QString VIDEO_DIRECTOR_DEFAULT
const QString VIDEO_SCREENSHOT_DEFAULT