27 (QEvent::Type) QEvent::registerEventType();
31 template <
typename DirListType>
36 const QStringList &image_extensions) :
37 m_videoFiles(video_files)
39 for (
const auto& ext : std::as_const(image_extensions))
40 m_imageExt.insert(ext.toLower());
44 [[maybe_unused]]
const QString &fq_dir_name)
override
49 void handleFile([[maybe_unused]]
const QString &file_name,
50 const QString &fq_file_name,
51 const QString &extension,
52 const QString &host)
override
56 LOG(VB_GENERAL, LOG_DEBUG,
57 QString(
"handleFile: %1 :: %2").arg(fq_file_name).arg(host));
59 if (m_imageExt.find(extension.toLower()) == m_imageExt.end())
61 m_videoFiles[fq_file_name].check =
false;
62 m_videoFiles[fq_file_name].host = host;
93 for (
const auto& host : std::as_const(hosts))
100 QStringList searchhosts;
104 QStringList::iterator iter = dirs.begin();
105 QStringList::iterator iter2;
106 while ( iter != dirs.end() )
108 if (iter->startsWith(
"myth://"))
111 QString host = sgurl.host().toLower();
112 QString path = sgurl.path();
120 iter = dirs.erase(iter);
123 if ((host == master) && (!mdirs.contains(path)))
129 else if (!searchhosts.contains(host))
133 searchhosts.append(host);
142 if ((!searchhosts.contains(*iter)) && (master != *iter))
144 for (iter2 = mdirs.begin(); iter2 != mdirs.end(); ++iter2)
149 0, *iter2,
"Videos"));
165 QList<QByteArray> image_types = QImageReader::supportedImageFormats();
166 QStringList imageExtensions;
167 for (
const auto & format : std::as_const(image_types))
168 imageExtensions.push_back(QString(format));
170 LOG(VB_GENERAL, LOG_INFO, QString(
"Beginning Video Scan."));
177 tr(
"Searching for video files"));
182 if (dir.startsWith(
"myth://"))
185 QString host = sgurl.host().toLower();
189 LOG(VB_GENERAL, LOG_ERR,
190 QString(
"Failed to scan :%1:").arg(dir));
203 QCoreApplication::postEvent(
m_parent,
210 slist << QString(
"added::%1").arg(
id);
212 slist << QString(
"moved::%1").arg(
id);
214 slist << QString(
"deleted::%1").arg(
id);
216 MythEvent me(
"VIDEO_LIST_CHANGE", slist);
230 [[maybe_unused]]
const QString &
filename)
247 FileCheckList::iterator iter;
251 tr(
"Verifying video files"));
256 QString lname =
file->GetFilename();
257 QString lhost =
file->GetHost().toLower();
258 if (!lname.isEmpty())
260 iter = files.find(lname);
261 if (iter != files.end())
263 if (lhost != iter->second.host)
267 remove.emplace_back(
file->GetID(), lname);
273 iter->second.check =
true;
276 else if (lhost.isEmpty())
280 remove.emplace_back(
file->GetID(), lname);
284 LOG(VB_GENERAL, LOG_INFO,
285 QString(
"Removing file SG(%1) :%2:")
287 remove.emplace_back(
file->GetID(), lname);
291 LOG(VB_GENERAL, LOG_WARNING,
292 QString(
"SG(%1) not available. Not removing file :%2:")
309 tr(
"Updating video database"));
311 for (
auto p = add.cbegin();
p != add.cend(); ++
p)
314 if (!
p->second.check)
320 if (hash !=
"NULL" && !hash.isEmpty())
327 LOG(VB_GENERAL, LOG_ERR,
328 QString(
"Hash %1 already exists in the "
329 "database, updating record %2 "
330 "with new filename %3")
331 .arg(hash).arg(
id).arg(
p->first));
338 p->first, QString(), hash,
344 QString(), QString(), QString(), QString(),
355 LOG(VB_GENERAL, LOG_INFO, QString(
"Adding : %1 : %2 : %3")
368 ret += remove.size();
369 for (
const auto & item : remove)
384 const QStringList &imageExtensions,
393 LOG(VB_GENERAL,LOG_INFO, QString(
"buildFileList directory = %1")
409 QApplication::postEvent(
m_dialog, pue);
433 "videoscanprogressdialog");
435 if (progressDlg->Create())
437 popupStack->
AddScreen(progressDlg,
false);
446 progressDlg =
nullptr;
454 LOG(VB_GENERAL, LOG_WARNING,
"Could not retrieve list of "
455 "available backends.");
471 if (!failedHosts.empty())
473 QString hosts = failedHosts.join(
" ");
474 QString msg = tr(
"Failed to Scan SG Video Hosts:\n\n%1\n\n"
475 "If they no longer exist please remove them")
490 *list <<
"QUERY_ACTIVE_BACKENDS";
void getExtensionIgnoreList(ext_ignore_list &ext_ignore) const
std::vector< std::pair< QString, bool > > ext_ignore_list
static FileAssociations & getFileAssociation()
This is a wrapper around QThread that does several additional things.
bool isRunning(void) const
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
QThread * qthread(void)
Returns the thread, this will always return the same pointer no matter how often you restart the thre...
void SendMessage(const QString &message)
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
static QString GenMythURL(const QString &host=QString(), int port=0, QString path=QString(), const QString &storageGroup=QString())
QString GetMasterHostName(void)
void SendEvent(const MythEvent &event)
bool GetBoolSetting(const QString &key, bool defaultval=false)
This class is used as a container for messages.
MythScreenStack * GetStack(const QString &Stackname)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
MythUIProgressDialog(QString message, MythScreenStack *parent, const char *name)
static const Type kEventType
std::vector< std::pair< int, QString > > PurgeList
bool getDataChanged() const
void SetDirs(QStringList dirs)
bool updateDB(const FileCheckList &add, const PurgeList &remove)
std::map< QString, CheckStruct > FileCheckList
~VideoScannerThread() override
void SendProgressEvent(uint progress, uint total=0, QString messsage=QString())
QStringList GetOfflineSGHosts(void)
MythUIProgressDialog * m_dialog
void SetProgressDialog(MythUIProgressDialog *dialog)
VideoMetadataListManager * m_dbMetadata
void SetHosts(const QStringList &hosts)
void run() override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
void verifyFiles(FileCheckList &files, PurgeList &remove)
QStringList m_offlineSGHosts
VideoScannerThread(QObject *parent)
bool buildFileList(const QString &directory, const QStringList &imageExtensions, FileCheckList &filelist) const
void removeOrphans(unsigned int id, const QString &filename)
QStringList m_liveSGHosts
QStringList m_directories
class VideoScannerThread * m_scanThread
void doScan(const QStringList &dirs)
DirListType & m_videoFiles
std::set< QString > image_ext
void handleFile(const QString &file_name, const QString &fq_file_name, const QString &extension, const QString &host) override
DirectoryHandler * newDir(const QString &dir_name, const QString &fq_dir_name) override
dirhandler(DirListType &video_files, const QStringList &image_extensions)
bool ScanVideoDirectory(const QString &start_path, DirectoryHandler *handler, const FileAssociations::ext_ignore_list &ext_disposition, bool list_unknown_extensions)
const QString VIDEO_INETREF_DEFAULT
const QString VIDEO_PLOT_DEFAULT
const QString VIDEO_TRAILER_DEFAULT
const QString VIDEO_BANNER_DEFAULT
const QString VIDEO_SCREENSHOT_DEFAULT
const QString VIDEO_FANART_DEFAULT
const QString VIDEO_RATING_DEFAULT
const QString VIDEO_DIRECTOR_DEFAULT
const QString VIDEO_COVERFILE_DEFAULT
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MythMainWindow * GetMythMainWindow(void)
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
bool RemoteGetActiveBackends(QStringList *list)
return list of backends currently connected to the master
QStringList GetVideoDirs()