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 : qAsConst(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;
68 using image_ext = std::set<QString>;
70 DirListType &m_videoFiles;
94 for (
const auto& host : qAsConst(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 : qAsConst(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);
229 [[maybe_unused]]
const QString &
filename)
246 FileCheckList::iterator iter;
250 tr(
"Verifying video files"));
255 QString lname =
file->GetFilename();
256 QString lhost =
file->GetHost().toLower();
257 if (!lname.isEmpty())
259 iter = files.find(lname);
260 if (iter != files.end())
262 if (lhost != iter->second.host)
266 remove.emplace_back(
file->GetID(), lname);
272 iter->second.check =
true;
275 else if (lhost.isEmpty())
279 remove.emplace_back(
file->GetID(), lname);
283 LOG(VB_GENERAL, LOG_INFO,
284 QString(
"Removing file SG(%1) :%2:")
286 remove.emplace_back(
file->GetID(), lname);
290 LOG(VB_GENERAL, LOG_WARNING,
291 QString(
"SG(%1) not available. Not removing file :%2:")
308 tr(
"Updating video database"));
310 for (
auto p = add.cbegin();
p != add.cend(); ++
p)
313 if (!
p->second.check)
319 if (hash !=
"NULL" && !hash.isEmpty())
326 LOG(VB_GENERAL, LOG_ERR,
327 QString(
"Hash %1 already exists in the "
328 "database, updating record %2 "
329 "with new filename %3")
330 .arg(hash).arg(
id).arg(
p->first));
337 p->first, QString(), hash,
343 QString(), QString(), QString(), QString(),
354 LOG(VB_GENERAL, LOG_INFO, QString(
"Adding : %1 : %2 : %3")
367 ret += remove.size();
368 for (
const auto & item : remove)
383 const QStringList &imageExtensions,
392 LOG(VB_GENERAL,LOG_INFO, QString(
"buildFileList directory = %1")
408 QApplication::postEvent(
m_dialog, pue);
432 "videoscanprogressdialog");
434 if (progressDlg->Create())
436 popupStack->
AddScreen(progressDlg,
false);
445 progressDlg =
nullptr;
453 LOG(VB_GENERAL, LOG_WARNING,
"Could not retrieve list of "
454 "available backends.");
470 if (!failedHosts.empty())
472 QString hosts = failedHosts.join(
" ");
473 QString msg = tr(
"Failed to Scan SG Video Hosts:\n\n%1\n\n"
474 "If they no longer exist please remove them")
void SendMessage(const QString &message)
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())
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().
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
void handleFile(const QString &file_name, const QString &fq_file_name, const QString &extension)
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
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()
DirectoryHandler * newDir(const QString &dir_name, [[maybe_unused]] const QString &fq_dir_name) override
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)
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