00001 #include <map>
00002
00003 #include <QDir>
00004 #include <QUrl>
00005
00006 #include "mythcorecontext.h"
00007 #include "dbaccess.h"
00008 #include "dirscan.h"
00009 #include "remoteutil.h"
00010 #include "mythcontext.h"
00011 #include "mythlogging.h"
00012 #include "videoutils.h"
00013 #include "storagegroup.h"
00014
00015 DirectoryHandler::~DirectoryHandler()
00016 {
00017 }
00018
00019 namespace
00020 {
00021 class ext_lookup
00022 {
00023 private:
00024 typedef std::map<QString, bool> ext_map;
00025 ext_map m_extensions;
00026 bool m_list_unknown;
00027
00028 public:
00029 ext_lookup(const FileAssociations::ext_ignore_list &ext_disposition,
00030 bool list_unknown) : m_list_unknown(list_unknown)
00031 {
00032 for (FileAssociations::ext_ignore_list::const_iterator p =
00033 ext_disposition.begin(); p != ext_disposition.end(); ++p)
00034 {
00035 m_extensions.insert(ext_map::value_type(p->first.toLower(),
00036 p->second));
00037 }
00038 }
00039
00040 bool extension_ignored(const QString &extension) const
00041 {
00042 ext_map::const_iterator p = m_extensions.find(extension.toLower());
00043 if (p != m_extensions.end())
00044 return p->second;
00045 return !m_list_unknown;
00046 }
00047 };
00048
00049 bool scan_dir(const QString &start_path, DirectoryHandler *handler,
00050 const ext_lookup &ext_settings)
00051 {
00052 QDir d(start_path);
00053
00054
00055 if (!d.exists())
00056 return false;
00057
00058 QFileInfoList list = d.entryInfoList();
00059
00060 if (!list.size())
00061 return true;
00062
00063 QDir dir_tester;
00064
00065 for (QFileInfoList::iterator p = list.begin(); p != list.end(); ++p)
00066 {
00067 if (p->fileName() == "." ||
00068 p->fileName() == ".." ||
00069 p->fileName() == "Thumbs.db")
00070 {
00071 continue;
00072 }
00073
00074 if (!p->isDir() &&
00075 ext_settings.extension_ignored(p->suffix())) continue;
00076
00077 bool add_as_file = true;
00078
00079 if (p->isDir())
00080 {
00081 add_as_file = false;
00082
00083 dir_tester.setPath(p->absoluteFilePath() + "/VIDEO_TS");
00084 QDir bd_dir_tester;
00085 bd_dir_tester.setPath(p->absoluteFilePath() + "/BDMV");
00086 if (dir_tester.exists() || bd_dir_tester.exists())
00087 {
00088 add_as_file = true;
00089 }
00090 else
00091 {
00092 #if 0
00093 LOG(VB_GENERAL, LOG_DEBUG,
00094 QString(" -- Dir : %1").arg(p->absoluteFilePath()));
00095 #endif
00096 DirectoryHandler *dh =
00097 handler->newDir(p->fileName(),
00098 p->absoluteFilePath());
00099
00100
00101
00102 (void) scan_dir(p->absoluteFilePath(), dh, ext_settings);
00103 }
00104 }
00105
00106 if (add_as_file)
00107 {
00108 #if 0
00109 LOG(VB_GENERAL, LOG_DEBUG,
00110 QString(" -- File : %1").arg(p->fileName()));
00111 #endif
00112 handler->handleFile(p->fileName(), p->absoluteFilePath(),
00113 p->suffix(), "");
00114 }
00115 }
00116
00117 return true;
00118 }
00119
00120 bool scan_sg_dir(const QString &start_path, const QString &host,
00121 const QString &base_path, DirectoryHandler *handler,
00122 const ext_lookup &ext_settings, bool isMaster = false)
00123 {
00124 QString path = start_path;
00125
00126 if (path.startsWith(base_path))
00127 path.remove(0, base_path.length());
00128
00129 if (!path.endsWith("/"))
00130 path += "/";
00131
00132 if (path == "/")
00133 path = "";
00134
00135 QStringList list;
00136 bool ok = false;
00137
00138 if (isMaster)
00139 {
00140 StorageGroup sg("Videos", host);
00141 list = sg.GetFileInfoList(start_path);
00142 ok = true;
00143 }
00144 else
00145 ok = RemoteGetFileList(host, start_path, &list, "Videos");
00146
00147 if (!ok || (!list.isEmpty() && list.at(0).startsWith("SLAVE UNREACHABLE")))
00148 {
00149 LOG(VB_GENERAL, LOG_INFO,
00150 QString("Backend : %1 : Is currently Unreachable. Skipping "
00151 "this one.") .arg(host));
00152 return false;
00153 }
00154
00155 if ((!list.size()) || (list.at(0) == "EMPTY LIST"))
00156 return true;
00157
00158 for (QStringList::iterator p = list.begin(); p != list.end(); ++p)
00159 {
00160 QStringList fInfo = p->split("::");
00161 QString type = fInfo.at(0);
00162 QString fileName = fInfo.at(1);
00163
00164 if (type == "nop")
00165 continue;
00166
00167 QFileInfo fi(fileName);
00168
00169 if ((type != "dir") &&
00170 ext_settings.extension_ignored(fi.suffix())) continue;
00171
00172 if (type == "dir" &&
00173 !fileName.endsWith("VIDEO_TS") &&
00174 !fileName.endsWith("BDMV"))
00175 {
00176 #if 0
00177 LOG(VB_GENERAL, LOG_DEBUG,
00178 QString(" -- Dir : %1").arg(fileName));
00179 #endif
00180 DirectoryHandler *dh =
00181 handler->newDir(fileName,
00182 start_path);
00183
00184
00185
00186
00187
00188 (void) scan_sg_dir(start_path + "/" + fileName, host, base_path,
00189 dh, ext_settings, isMaster);
00190 }
00191 else
00192 {
00193 QString suffix;
00194 QString URL;
00195
00196 if (fileName.endsWith("VIDEO_TS") || fileName.endsWith("BDMV"))
00197 {
00198 if (path.startsWith("/"))
00199 path = path.right(path.length() - 1);
00200 if (path.endsWith("/"))
00201 path = path.left(path.length() - 1);
00202 QStringList upDirs = path.split("/");
00203 if (upDirs.count() > 1)
00204 fileName = upDirs.takeLast();
00205 else
00206 fileName = path;
00207 suffix = "";
00208 URL = path;
00209 }
00210 else
00211 {
00212 suffix = fi.suffix();
00213 URL = QString("%1/%2").arg(path).arg(fileName);
00214 }
00215
00216 URL.replace("//","/");
00217
00218 if (URL.startsWith("/"))
00219 URL = URL.right(URL.length() - 1);
00220 #if 0
00221 LOG(VB_GENERAL, LOG_GENERAL,
00222 QString(" -- File Filename: %1 URL: %2 Suffix: %3 Host: %4")
00223 .arg(fileName).arg(URL).arg(suffix).arg(QString(host)));
00224 #endif
00225 handler->handleFile(fileName, URL, fi.suffix(), QString(host));
00226 }
00227 }
00228
00229 return true;
00230 }
00231 }
00232
00233 bool ScanVideoDirectory(const QString &start_path, DirectoryHandler *handler,
00234 const FileAssociations::ext_ignore_list &ext_disposition,
00235 bool list_unknown_extensions)
00236 {
00237 ext_lookup extlookup(ext_disposition, list_unknown_extensions);
00238
00239 bool pathScanned = true;
00240
00241 if (!start_path.startsWith("myth://"))
00242 {
00243 LOG(VB_GENERAL, LOG_INFO,
00244 QString("MythVideo::ScanVideoDirectory Scanning (%1)")
00245 .arg(start_path));
00246
00247 if (!scan_dir(start_path, handler, extlookup))
00248 {
00249 LOG(VB_GENERAL, LOG_ERR,
00250 QString("MythVideo::ScanVideoDirectory failed to scan %1")
00251 .arg(start_path));
00252 pathScanned = false;
00253 }
00254 }
00255 else
00256 {
00257 LOG(VB_GENERAL, LOG_INFO,
00258 QString("MythVideo::ScanVideoDirectory Scanning Group (%1)")
00259 .arg(start_path));
00260 QUrl sgurl = start_path;
00261 QString host = sgurl.host();
00262 QString path = sgurl.path();
00263
00264 if (!scan_sg_dir(path, host, path, handler, extlookup,
00265 (gCoreContext->IsMasterHost(host) &&
00266 (gCoreContext->GetHostName().toLower() == host.toLower()))))
00267 {
00268 LOG(VB_GENERAL, LOG_ERR,
00269 QString("MythVideo::ScanVideoDirectory failed to scan %1 ")
00270 .arg(host));
00271 pathScanned = false;
00272 }
00273 }
00274
00275 return pathScanned;
00276 }