MythTV  master
videoscan.cpp
Go to the documentation of this file.
1 
2 #include "videoscan.h"
3 
4 #include <QApplication>
5 #include <QImageReader>
6 #include <QUrl>
7 #include <utility>
8 
9 // mythtv
10 #include "libmyth/mythcontext.h"
11 #include "libmythbase/mythdate.h"
12 #include "libmythbase/mythevent.h"
14 #include "libmythbase/remoteutil.h"
19 
20 // libmythmetadata
22 #include "videoutils.h"
23 #include "globals.h"
24 #include "dbaccess.h"
25 #include "dirscan.h"
26 
27 const QEvent::Type VideoScanChanges::kEventType =
28  (QEvent::Type) QEvent::registerEventType();
29 
30 namespace
31 {
32  template <typename DirListType>
34  {
35  public:
36  dirhandler(DirListType &video_files,
37  const QStringList &image_extensions) :
38  m_videoFiles(video_files)
39  {
40  for (const auto& ext : std::as_const(image_extensions))
41  m_imageExt.insert(ext.toLower());
42  }
43 
44  DirectoryHandler *newDir([[maybe_unused]] const QString &dir_name,
45  [[maybe_unused]] const QString &fq_dir_name) override // DirectoryHandler
46  {
47  return this;
48  }
49 
50  void handleFile([[maybe_unused]] const QString &file_name,
51  const QString &fq_file_name,
52  const QString &extension,
53  const QString &host) override // DirectoryHandler
54 
55  {
56 #if 0
57  LOG(VB_GENERAL, LOG_DEBUG,
58  QString("handleFile: %1 :: %2").arg(fq_file_name).arg(host));
59 #endif
60  if (m_imageExt.find(extension.toLower()) == m_imageExt.end())
61  {
62  m_videoFiles[fq_file_name].check = false;
63  m_videoFiles[fq_file_name].host = host;
64  }
65  }
66 
67  private:
68  using image_ext = std::set<QString>;
70  DirListType &m_videoFiles;
71  };
72 }
73 
76 
78  MThread("VideoScanner"),
79  m_parent(parent),
80  m_hasGUI(gCoreContext->HasGUI()),
81  m_dbMetadata(new VideoMetadataListManager)
82 {
83  m_listUnknown = gCoreContext->GetBoolSetting("VideoListUnknownFiletypes", false);
84 }
85 
87 {
88  delete m_dbMetadata;
89 }
90 
91 void VideoScannerThread::SetHosts(const QStringList &hosts)
92 {
93  m_liveSGHosts.clear();
94  for (const auto& host : std::as_const(hosts))
95  m_liveSGHosts << host.toLower();
96 }
97 
98 void VideoScannerThread::SetDirs(QStringList dirs)
99 {
100  QString master = gCoreContext->GetMasterHostName().toLower();
101  QStringList searchhosts;
102  QStringList mdirs;
103  m_offlineSGHosts.clear();
104 
105  QStringList::iterator iter = dirs.begin();
106  QStringList::iterator iter2;
107  while ( iter != dirs.end() )
108  {
109  if (iter->startsWith("myth://"))
110  {
111  QUrl sgurl = *iter;
112  QString host = sgurl.host().toLower();
113  QString path = sgurl.path();
114 
115  if (!m_liveSGHosts.contains(host))
116  {
117  // mark host as offline to warn user
118  if (!m_offlineSGHosts.contains(host))
119  m_offlineSGHosts.append(host);
120  // erase from directory list to skip scanning
121  iter = dirs.erase(iter);
122  continue;
123  }
124  if ((host == master) && (!mdirs.contains(path)))
125  {
126  // collect paths defined on master backend so other
127  // online backends can be set to fall through to them
128  mdirs.append(path);
129  }
130  else if (!searchhosts.contains(host))
131  {
132  // mark host as having directories defined so it
133  // does not fall through to those on the master
134  searchhosts.append(host);
135  }
136  }
137 
138  ++iter;
139  }
140 
141  for (iter = m_liveSGHosts.begin(); iter != m_liveSGHosts.end(); ++iter)
142  {
143  if ((!searchhosts.contains(*iter)) && (master != *iter))
144  {
145  for (iter2 = mdirs.begin(); iter2 != mdirs.end(); ++iter2)
146  {
147  // backend is online, but has no directories listed
148  // fall back to those on the master backend
149  dirs.append(MythCoreContext::GenMythURL(*iter,
150  0, *iter2, "Videos"));
151  }
152  }
153  }
154 
155  m_directories = dirs;
156 }
157 
159 {
160  RunProlog();
161 
164  m_dbMetadata->setList(ml);
165 
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));
170 
171  LOG(VB_GENERAL, LOG_INFO, QString("Beginning Video Scan."));
172 
173  uint counter = 0;
174  FileCheckList fs_files;
175 
176  if (m_hasGUI)
177  SendProgressEvent(counter, (uint)m_directories.size(),
178  tr("Searching for video files"));
179  for (const auto & dir : std::as_const(m_directories))
180  {
181  if (!buildFileList(dir, imageExtensions, fs_files))
182  {
183  if (dir.startsWith("myth://"))
184  {
185  QUrl sgurl = dir;
186  QString host = sgurl.host().toLower();
187 
188  m_liveSGHosts.removeAll(host);
189 
190  LOG(VB_GENERAL, LOG_ERR,
191  QString("Failed to scan :%1:").arg(dir));
192  }
193  }
194  if (m_hasGUI)
195  SendProgressEvent(++counter);
196  }
197 
198  PurgeList db_remove;
199  verifyFiles(fs_files, db_remove);
200  m_dbDataChanged = updateDB(fs_files, db_remove);
201 
202  if (m_dbDataChanged)
203  {
204  QCoreApplication::postEvent(m_parent,
206  m_delList));
207 
208  QStringList slist;
209 
210  for (int id : std::as_const(m_addList))
211  slist << QString("added::%1").arg(id);
212  for (int id : std::as_const(m_movList))
213  slist << QString("moved::%1").arg(id);
214  for (int id : std::as_const(m_delList))
215  slist << QString("deleted::%1").arg(id);
216 
217  MythEvent me("VIDEO_LIST_CHANGE", slist);
218 
219  gCoreContext->SendEvent(me);
220  }
221  else
222  {
223  gCoreContext->SendMessage("VIDEO_LIST_NO_CHANGE");
224  }
225 
226  RunEpilog();
227 }
228 
229 
231  [[maybe_unused]] const QString &filename)
232 {
233  // TODO: use single DB connection for all calls
234  if (m_removeAll)
235  m_dbMetadata->purgeByID(id);
236 
237  if (!m_keepAll && !m_removeAll)
238  {
239  m_removeAll = true;
240  m_dbMetadata->purgeByID(id);
241  }
242 }
243 
245  PurgeList &remove)
246 {
247  int counter = 0;
248  FileCheckList::iterator iter;
249 
250  if (m_hasGUI)
251  SendProgressEvent(counter, (uint)m_dbMetadata->getList().size(),
252  tr("Verifying video files"));
253 
254  // For every file we know about, check to see if it still exists.
255  for (const auto & file : m_dbMetadata->getList())
256  {
257  QString lname = file->GetFilename();
258  QString lhost = file->GetHost().toLower();
259  if (!lname.isEmpty())
260  {
261  iter = files.find(lname);
262  if (iter != files.end())
263  {
264  if (lhost != iter->second.host)
265  {
266  // file has changed hosts
267  // add to delete list for further processing
268  remove.emplace_back(file->GetID(), lname);
269  }
270  else
271  {
272  // file is on disk on the proper host and in the database
273  // we're done with it
274  iter->second.check = true;
275  }
276  }
277  else if (lhost.isEmpty())
278  {
279  // If it's only in the database, and not on a host we
280  // cannot reach, mark it as for removal later.
281  remove.emplace_back(file->GetID(), lname);
282  }
283  else if (m_liveSGHosts.contains(lhost))
284  {
285  LOG(VB_GENERAL, LOG_INFO,
286  QString("Removing file SG(%1) :%2:")
287  .arg(lhost, lname));
288  remove.emplace_back(file->GetID(), lname);
289  }
290  else
291  {
292  LOG(VB_GENERAL, LOG_WARNING,
293  QString("SG(%1) not available. Not removing file :%2:")
294  .arg(lhost, lname));
295  if (!m_offlineSGHosts.contains(lhost))
296  m_offlineSGHosts.append(lhost);
297  }
298  }
299  if (m_hasGUI)
300  SendProgressEvent(++counter);
301  }
302 }
303 
304 bool VideoScannerThread::updateDB(const FileCheckList &add, const PurgeList &remove)
305 {
306  int ret = 0;
307  uint counter = 0;
308  if (m_hasGUI)
309  SendProgressEvent(counter, (uint)(add.size() + remove.size()),
310  tr("Updating video database"));
311 
312  for (auto p = add.cbegin(); p != add.cend(); ++p)
313  {
314  // add files not already in the DB
315  if (!p->second.check)
316  {
317  int id = -1;
318 
319  // Are we sure this needs adding? Let's check our Hash list.
320  QString hash = VideoMetadata::VideoFileHash(p->first, p->second.host);
321  if (hash != "NULL" && !hash.isEmpty())
322  {
323  id = VideoMetadata::UpdateHashedDBRecord(hash, p->first, p->second.host);
324  if (id != -1)
325  {
326  // Whew, that was close. Let's remove that thing from
327  // our purge list, too.
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));
333  m_movList.append(id);
334  }
335  }
336  if (id == -1)
337  {
338  VideoMetadata newFile(
339  p->first, QString(), hash,
345  QString(), QString(), QString(), QString(),
346  QString(),
348  QDate::fromString("0000-00-00","YYYY-MM-DD"),
349  VIDEO_INETREF_DEFAULT, 0, QString(),
351  0.0, VIDEO_RATING_DEFAULT, 0, 0,
352  0, 0,
353  MythDate::current().date(),
355 
356  LOG(VB_GENERAL, LOG_INFO, QString("Adding : %1 : %2 : %3")
357  .arg(newFile.GetHost(), newFile.GetFilename(), hash));
358  newFile.SetHost(p->second.host);
359  newFile.SaveToDatabase();
360  m_addList << newFile.GetID();
361  }
362  ret += 1;
363  }
364  if (m_hasGUI)
365  SendProgressEvent(++counter);
366  }
367 
368  // When prompting is restored, account for the answer here.
369  ret += remove.size();
370  for (const auto & item : remove)
371  {
372  if (!m_movList.contains(item.first))
373  {
374  removeOrphans(item.first, item.second);
375  m_delList << item.first;
376  }
377  if (m_hasGUI)
378  SendProgressEvent(++counter);
379  }
380 
381  return ret > 0;
382 }
383 
384 bool VideoScannerThread::buildFileList(const QString &directory,
385  const QStringList &imageExtensions,
386  FileCheckList &filelist) const
387 {
388  // TODO: FileCheckList is a std::map, keyed off the filename. In the event
389  // multiple backends have access to shared storage, the potential exists
390  // for files to be scanned onto the wrong host. Add in some logic to prefer
391  // the backend with the content stored in a storage group determined to be
392  // local.
393 
394  LOG(VB_GENERAL,LOG_INFO, QString("buildFileList directory = %1")
395  .arg(directory));
398 
399  dirhandler<FileCheckList> dh(filelist, imageExtensions);
400  return ScanVideoDirectory(directory, &dh, ext_list, m_listUnknown);
401 }
402 
404  QString messsage)
405 {
406  if (!m_dialog)
407  return;
408 
409  auto *pue = new ProgressUpdateEvent(progress, total, std::move(messsage));
410  QApplication::postEvent(m_dialog, pue);
411 }
412 
414  : m_scanThread(new VideoScannerThread(this))
415 {
416 }
417 
419 {
420  if (m_scanThread && m_scanThread->wait())
421  delete m_scanThread;
422 }
423 
424 void VideoScanner::doScan(const QStringList &dirs)
425 {
426  if (m_scanThread->isRunning())
427  return;
428 
429  if (gCoreContext->HasGUI())
430  {
431  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
432 
433  auto *progressDlg = new MythUIProgressDialog("", popupStack,
434  "videoscanprogressdialog");
435 
436  if (progressDlg->Create())
437  {
438  popupStack->AddScreen(progressDlg, false);
439  connect(m_scanThread->qthread(), &QThread::finished,
440  progressDlg, &MythScreenType::Close);
441  connect(m_scanThread->qthread(), &QThread::finished,
443  }
444  else
445  {
446  delete progressDlg;
447  progressDlg = nullptr;
448  }
449  m_scanThread->SetProgressDialog(progressDlg);
450  }
451 
452  QStringList hosts;
453  if (!RemoteGetActiveBackends(&hosts))
454  {
455  LOG(VB_GENERAL, LOG_WARNING, "Could not retrieve list of "
456  "available backends.");
457  hosts.clear();
458  }
459  m_scanThread->SetHosts(hosts);
460  m_scanThread->SetDirs(dirs);
461  m_scanThread->start();
462 }
463 
465 {
466  doScan(GetVideoDirs());
467 }
468 
470 {
471  QStringList failedHosts = m_scanThread->GetOfflineSGHosts();
472  if (!failedHosts.empty())
473  {
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")
477  .arg(hosts);
478 
479  ShowOkPopup(msg);
480  }
481 
483 }
484 
VideoScanner::finished
void finished(bool)
VideoMetadata
Definition: videometadata.h:24
mythevent.h
MythCoreContext::SendMessage
void SendMessage(const QString &message)
Definition: mythcorecontext.cpp:1525
anonymous_namespace{videoscan.cpp}::dirhandler::handleFile
void handleFile([[maybe_unused]] const QString &file_name, const QString &fq_file_name, const QString &extension, const QString &host) override
Definition: videoscan.cpp:50
MThread::start
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
Definition: mthread.cpp:283
MythCoreContext::GetMasterHostName
QString GetMasterHostName(void)
Definition: mythcorecontext.cpp:811
VideoScannerThread::m_listUnknown
bool m_listUnknown
Definition: videoscan.h:101
VideoScanner::VideoScanner
VideoScanner()
Definition: videoscan.cpp:413
VideoScannerThread::SendProgressEvent
void SendProgressEvent(uint progress, uint total=0, QString messsage=QString())
Definition: videoscan.cpp:403
VideoScannerThread::m_keepAll
bool m_keepAll
Definition: videoscan.h:103
anonymous_namespace{videoscan.cpp}::dirhandler::m_videoFiles
DirListType & m_videoFiles
Definition: videoscan.cpp:70
FileAssociations::getExtensionIgnoreList
void getExtensionIgnoreList(ext_ignore_list &ext_ignore) const
Definition: dbaccess.cpp:816
dirscan.h
VideoMetadata::GetHost
const QString & GetHost() const
Definition: videometadata.cpp:1834
VideoMetadataListManager
Definition: videometadatalistmanager.h:10
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:383
VideoScanner::doScan
void doScan(const QStringList &dirs)
Definition: videoscan.cpp:424
progress
bool progress
Definition: mythcommflag.cpp:69
MThread::wait
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:300
mythscreenstack.h
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
anonymous_namespace{videoscan.cpp}::dirhandler::m_imageExt
image_ext m_imageExt
Definition: videoscan.cpp:69
mythdialogbox.h
MythScreenStack
Definition: mythscreenstack.h:16
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MThread::RunProlog
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:196
VideoMetadataListManager::getList
const metadata_list & getList() const
Definition: videometadatalistmanager.cpp:168
anonymous_namespace{videoscan.cpp}::dirhandler::newDir
DirectoryHandler * newDir([[maybe_unused]] const QString &dir_name, [[maybe_unused]] const QString &fq_dir_name) override
Definition: videoscan.cpp:44
VideoMetadataListManager::setList
void setList(metadata_list &list)
Definition: videometadatalistmanager.cpp:162
build_compdb.file
file
Definition: build_compdb.py:55
VideoScannerThread::GetOfflineSGHosts
QStringList GetOfflineSGHosts(void)
Definition: videoscan.h:72
remoteutil.h
VideoScannerThread::m_movList
QList< int > m_movList
Definition: videoscan.h:113
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
mythprogressdialog.h
VideoScannerThread::buildFileList
bool buildFileList(const QString &directory, const QStringList &imageExtensions, FileCheckList &filelist) const
Definition: videoscan.cpp:384
MythUIProgressDialog::MythUIProgressDialog
MythUIProgressDialog(QString message, MythScreenStack *parent, const char *name)
Definition: mythprogressdialog.h:63
dbaccess.h
VideoScanner::m_scanThread
class VideoScannerThread * m_scanThread
Definition: videoscan.h:40
VideoMetadataListManager::loadAllFromDatabase
static void loadAllFromDatabase(metadata_list &items, const QString &sql="", const QString &bindValue="")
Load videometadata database into memory.
Definition: videometadatalistmanager.cpp:128
videoscan.h
VideoScannerThread
Definition: videoscan.h:60
ProgressUpdateEvent
Definition: mythprogressdialog.h:16
ParentalLevel::plLowest
@ plLowest
Definition: parentalcontrols.h:13
mythdate.h
VideoMetadata::GetFilename
const QString & GetFilename() const
Definition: videometadata.cpp:1814
mythlogging.h
MythCoreContext::GenMythURL
static QString GenMythURL(const QString &host=QString(), int port=0, QString path=QString(), const QString &storageGroup=QString())
Definition: mythcorecontext.cpp:764
VideoScannerThread::m_dialog
MythUIProgressDialog * m_dialog
Definition: videoscan.h:110
GetVideoDirs
QStringList GetVideoDirs()
Definition: videoutils.cpp:116
MythCoreContext::SendEvent
void SendEvent(const MythEvent &event)
Definition: mythcorecontext.cpp:1538
hardwareprofile.config.p
p
Definition: config.py:33
MythUIProgressDialog
Definition: mythprogressdialog.h:59
globals.h
FileAssociations::ext_ignore_list
std::vector< std::pair< QString, bool > > ext_ignore_list
Definition: dbaccess.h:155
VideoScannerThread::m_addList
QList< int > m_addList
Definition: videoscan.h:112
anonymous_namespace{videoscan.cpp}::dirhandler::dirhandler
dirhandler(DirListType &video_files, const QStringList &image_extensions)
Definition: videoscan.cpp:36
VideoMetadata::UpdateHashedDBRecord
static int UpdateHashedDBRecord(const QString &hash, const QString &file_name, const QString &host)
Definition: videometadata.cpp:1070
VideoScannerThread::SetDirs
void SetDirs(QStringList dirs)
Definition: videoscan.cpp:98
VideoMetadata::SaveToDatabase
void SaveToDatabase()
Definition: videometadata.cpp:1949
VIDEO_COVERFILE_DEFAULT
const QString VIDEO_COVERFILE_DEFAULT
Definition: globals.cpp:25
VIDEO_PLOT_DEFAULT
const QString VIDEO_PLOT_DEFAULT
Definition: globals.cpp:32
MythUIType::m_parent
MythUIType * m_parent
Definition: mythuitype.h:294
VideoScannerThread::m_liveSGHosts
QStringList m_liveSGHosts
Definition: videoscan.h:106
MThread::qthread
QThread * qthread(void)
Returns the thread, this will always return the same pointer no matter how often you restart the thre...
Definition: mthread.cpp:233
MThread::RunEpilog
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:209
VideoScanChanges::kEventType
static const Type kEventType
Definition: videoscan.h:57
VIDEO_TRAILER_DEFAULT
const QString VIDEO_TRAILER_DEFAULT
Definition: globals.cpp:26
uint
unsigned int uint
Definition: compat.h:81
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
VideoScannerThread::m_dbMetadata
VideoMetadataListManager * m_dbMetadata
Definition: videoscan.h:109
VideoScannerThread::m_removeAll
bool m_removeAll
Definition: videoscan.h:102
VIDEO_INETREF_DEFAULT
const QString VIDEO_INETREF_DEFAULT
Definition: globals.cpp:24
VIDEO_FANART_DEFAULT
const QString VIDEO_FANART_DEFAULT
Definition: globals.cpp:29
videometadatalistmanager.h
VideoScannerThread::m_delList
QList< int > m_delList
Definition: videoscan.h:114
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:34
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:910
FileAssociations::getFileAssociation
static FileAssociations & getFileAssociation()
Definition: dbaccess.cpp:836
VideoMetadataListManager::purgeByID
bool purgeByID(unsigned int db_id)
Definition: videometadatalistmanager.cpp:190
VideoScannerThread::m_dbDataChanged
bool m_dbDataChanged
Definition: videoscan.h:115
VideoScannerThread::SetProgressDialog
void SetProgressDialog(MythUIProgressDialog *dialog)
Definition: videoscan.h:71
ScanVideoDirectory
bool ScanVideoDirectory(const QString &start_path, DirectoryHandler *handler, const FileAssociations::ext_ignore_list &ext_disposition, bool list_unknown_extensions)
Definition: dirscan.cpp:229
VideoMetadata::SetHost
void SetHost(const QString &host)
Definition: videometadata.cpp:1839
VideoScannerThread::run
void run() override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: videoscan.cpp:158
VideoScannerThread::~VideoScannerThread
~VideoScannerThread() override
Definition: videoscan.cpp:86
VIDEO_RATING_DEFAULT
const QString VIDEO_RATING_DEFAULT
Definition: globals.cpp:30
VideoScannerThread::m_parent
QObject * m_parent
Definition: videoscan.h:99
mythcontext.h
MThread
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:48
VideoScannerThread::VideoScannerThread
VideoScannerThread(QObject *parent)
Definition: videoscan.cpp:77
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
MThread::isRunning
bool isRunning(void) const
Definition: mthread.cpp:263
VideoMetadata::GetID
unsigned int GetID() const
Definition: videometadata.cpp:1734
VideoScannerThread::verifyFiles
void verifyFiles(FileCheckList &files, PurgeList &remove)
Definition: videoscan.cpp:244
VideoScanChanges
Definition: videoscan.h:44
VideoScannerThread::removeOrphans
void removeOrphans(unsigned int id, const QString &filename)
Definition: videoscan.cpp:230
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:322
VideoMetadataListManager::metadata_list
std::list< VideoMetadataPtr > metadata_list
Definition: videometadatalistmanager.h:14
VideoScanner::~VideoScanner
~VideoScanner() override
Definition: videoscan.cpp:418
VideoScannerThread::updateDB
bool updateDB(const FileCheckList &add, const PurgeList &remove)
Definition: videoscan.cpp:304
VideoScannerThread::m_offlineSGHosts
QStringList m_offlineSGHosts
Definition: videoscan.h:107
VideoScannerThread::FileCheckList
std::map< QString, CheckStruct > FileCheckList
Definition: videoscan.h:86
VideoScannerThread::m_hasGUI
bool m_hasGUI
Definition: videoscan.h:104
MythCoreContext::HasGUI
bool HasGUI(void) const
Definition: mythcorecontext.cpp:1746
VIDEO_YEAR_DEFAULT
static constexpr uint16_t VIDEO_YEAR_DEFAULT
Definition: videometadata.h:18
VIDEO_BANNER_DEFAULT
const QString VIDEO_BANNER_DEFAULT
Definition: globals.cpp:28
VideoScannerThread::SetHosts
void SetHosts(const QStringList &hosts)
Definition: videoscan.cpp:91
anonymous_namespace{videoscan.cpp}::dirhandler
Definition: videoscan.cpp:33
anonymous_namespace{videoscan.cpp}::dirhandler::image_ext
std::set< QString > image_ext
Definition: videoscan.cpp:68
build_compdb.filename
filename
Definition: build_compdb.py:21
VideoMetadata::VideoFileHash
static QString VideoFileHash(const QString &file_name, const QString &host)
Definition: videometadata.cpp:1118
DirectoryHandler
Definition: dirscan.h:6
mythmainwindow.h
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
VideoScannerThread::m_directories
QStringList m_directories
Definition: videoscan.h:105
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:566
VideoScannerThread::getDataChanged
bool getDataChanged() const
Definition: videoscan.h:73
VideoScanner::finishedScan
void finishedScan()
Definition: videoscan.cpp:469
videoutils.h
RemoteGetActiveBackends
bool RemoteGetActiveBackends(QStringList *list)
return list of backends currently connected to the master
Definition: remoteutil.cpp:576
dirhandler
Definition: videolist.cpp:1141
VideoScannerThread::PurgeList
std::vector< std::pair< int, QString > > PurgeList
Definition: videoscan.h:85
VIDEO_DIRECTOR_DEFAULT
const QString VIDEO_DIRECTOR_DEFAULT
Definition: globals.cpp:23
VIDEO_SCREENSHOT_DEFAULT
const QString VIDEO_SCREENSHOT_DEFAULT
Definition: globals.cpp:27
VideoScanner::doScanAll
void doScanAll(void)
Definition: videoscan.cpp:464