Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

StorageGroup method renames, enhancements, and HTML Setup helper

- Rename FindRecordingFile() -> FindFile()
- Rename FindRecordingDir() -> FindFileDir()
- Add a 'recursive' option to GetFileList().  Default is false, but
  can be turned on to get a list of all files below the given path.
- Add a GetDirFileList() to support GetFileList().  GetDirFileList() itself
  is recursive & calls itself when the recursive arg to GetFileList() is true.
- Make /Content/GetFileList call StorageGroup::GetFileList() with the
  recursive arg set to true to get all files in the Storage Group.
- Add relative path as a 4th arg to the 'file' result from GetFileInfoList()
- Add support to the /Config/FileBrowser API to allow browsing of a Storage
  Group instead of a filesystem.  This is useful for picking a file from an
  existing Storage Group, such as we may use for the channel icon chooser
  in the HTML Setup.

NOTE: This modifies the binary API version, so make clean, etc..
  • Loading branch information...
commit 7255d463cb83d8dbf81669fe2738d6572f215bd0 1 parent 4cba1a3
@cpinkham cpinkham authored
View
2  mythtv/libs/libmyth/programinfo.cpp
@@ -2007,7 +2007,7 @@ QString ProgramInfo::GetPlaybackURL(
// Check to see if the file exists locally
StorageGroup sgroup(storagegroup);
//VERBOSE(VB_FILE, LOC +QString("GetPlaybackURL: CHECKING SG : %1 : ").arg(tmpURL));
- tmpURL = sgroup.FindRecordingFile(basename);
+ tmpURL = sgroup.FindFile(basename);
if (!tmpURL.isEmpty())
{
View
2  mythtv/libs/libmythbase/mythversion.h
@@ -12,7 +12,7 @@
/// Update this whenever the plug-in API changes.
/// Including changes in the libmythbase, libmyth, libmythtv, libmythav* and
/// libmythui class methods used by plug-ins.
-#define MYTH_BINARY_VERSION "0.25.20110409-1"
+#define MYTH_BINARY_VERSION "0.25.20110414-1"
/** \brief Increment this whenever the MythTV network protocol changes.
*
View
84 mythtv/libs/libmythbase/storagegroup.cpp
@@ -64,6 +64,7 @@ void StorageGroup::StaticInit(void)
m_staticInitDone = true;
+ m_builtinGroups["ChannelIcons"] = GetConfDir() + "/ChannelIcons";
m_builtinGroups["Themes"] = GetConfDir() + "/themes";
m_builtinGroups["Temp"] = GetConfDir() + "/tmp";
@@ -181,7 +182,50 @@ void StorageGroup::Init(const QString group, const QString hostname,
}
}
-QStringList StorageGroup::GetFileList(QString Path)
+QStringList StorageGroup::GetDirFileList(QString dir, QString base,
+ bool recursive)
+{
+ QStringList files;
+ QDir d(dir);
+
+ if (!d.exists())
+ return files;
+
+ if (base.split("/").size() > 20)
+ {
+ VERBOSE(VB_IMPORTANT, LOC_ERR + "GetDirFileList(), 20 levels "
+ "deep, possible directory loop detected.");
+ return files;
+ }
+
+ if (!base.isEmpty())
+ base += "/";
+
+ if (recursive)
+ {
+ QStringList list =
+ d.entryList(QDir::Dirs|QDir::NoDotAndDotDot|QDir::Readable);
+
+ for (QStringList::iterator p = list.begin(); p != list.end(); ++p)
+ {
+ VERBOSE(VB_FILE+VB_EXTRA, LOC +
+ QString("GetDirFileList: Dir: %1/%2").arg(base).arg(*p));
+ files << GetDirFileList(dir + "/" + *p, base + *p, true);
+ }
+ }
+
+ QStringList list = d.entryList(QDir::Files|QDir::Readable);
+ for (QStringList::iterator p = list.begin(); p != list.end(); ++p)
+ {
+ VERBOSE(VB_FILE+VB_EXTRA, LOC + QString("GetDirFileList: File: %1%2")
+ .arg(base).arg(*p));
+ files.append(base + *p);
+ }
+
+ return files;
+}
+
+QStringList StorageGroup::GetFileList(QString Path, bool recursive)
{
QStringList files;
QString tmpDir;
@@ -193,15 +237,7 @@ QStringList StorageGroup::GetFileList(QString Path)
d.setPath(tmpDir);
if (d.exists())
- {
- VERBOSE(VB_FILE, LOC + QString("GetFileList: Reading '%1'").arg(tmpDir));
- QStringList list = d.entryList(QDir::Files|QDir::Readable);
- for (QStringList::iterator p = list.begin(); p != list.end(); ++p)
- {
- VERBOSE(VB_FILE+VB_EXTRA, LOC + QString("GetFileList: (%1)").arg(*p));
- files.append(*p);
- }
- }
+ files << GetDirFileList(tmpDir, Path, recursive);
}
return files;
@@ -210,6 +246,7 @@ QStringList StorageGroup::GetFileList(QString Path)
QStringList StorageGroup::GetFileInfoList(QString Path)
{
QStringList files;
+ QString relPath;
bool badPath = true;
if (Path.isEmpty() || Path == "/")
@@ -224,6 +261,10 @@ QStringList StorageGroup::GetFileInfoList(QString Path)
{
if (Path.startsWith(*it))
{
+ relPath = Path;
+ relPath.replace(*it,"");
+ if (relPath.startsWith("/"))
+ relPath.replace(0,1,"");
badPath = false;
}
}
@@ -255,7 +296,8 @@ QStringList StorageGroup::GetFileInfoList(QString Path)
if (p->isDir())
tmp = QString("dir::%1::0").arg(p->fileName());
else
- tmp = QString("file::%1::%2").arg(p->fileName()).arg(p->size());
+ tmp = QString("file::%1::%2::%3%4").arg(p->fileName()).arg(p->size())
+ .arg(relPath).arg(p->fileName());
VERBOSE(VB_FILE+VB_EXTRA, LOC + QString("GetFileInfoList: (%1)").arg(tmp));
files.append(tmp);
@@ -307,7 +349,7 @@ QStringList StorageGroup::GetFileInfo(QString filename)
if (!FileExists(filename))
{
searched = true;
- filename = FindRecordingFile(filename);
+ filename = FindFile(filename);
}
if ((searched && !filename.isEmpty()) ||
@@ -512,31 +554,31 @@ bool StorageGroup::FindDirs(const QString group, const QString hostname,
return found;
}
-QString StorageGroup::FindRecordingFile(QString filename)
+QString StorageGroup::FindFile(QString filename)
{
- VERBOSE(VB_FILE, LOC + QString("FindRecordingFile: Searching for '%1'")
+ VERBOSE(VB_FILE, LOC + QString("FindFile: Searching for '%1'")
.arg(filename));
- QString recDir = FindRecordingDir(filename);
+ QString recDir = FindFileDir(filename);
QString result = "";
if (!recDir.isEmpty())
{
result = recDir + "/" + filename;
- VERBOSE(VB_FILE, LOC + QString("FindRecordingFile: Found '%1'")
+ VERBOSE(VB_FILE, LOC + QString("FindFile: Found '%1'")
.arg(result));
}
else
{
VERBOSE(VB_FILE, LOC_ERR +
- QString("FindRecordingFile: Unable to find '%1'!")
+ QString("FindFile: Unable to find '%1'!")
.arg(filename));
}
return result;
}
-QString StorageGroup::FindRecordingDir(QString filename)
+QString StorageGroup::FindFileDir(QString filename)
{
QString result = "";
QFileInfo checkFile("");
@@ -545,7 +587,7 @@ QString StorageGroup::FindRecordingDir(QString filename)
while (curDir < m_dirlist.size())
{
QString testFile = m_dirlist[curDir] + "/" + filename;
- VERBOSE(VB_FILE, LOC + QString("FindRecordingDir: Checking '%1' for '%2'")
+ VERBOSE(VB_FILE, LOC + QString("FindFileDir: Checking '%1' for '%2'")
.arg(m_dirlist[curDir]).arg(testFile));
checkFile.setFile(testFile);
if (checkFile.exists() || checkFile.isSymLink())
@@ -571,14 +613,14 @@ QString StorageGroup::FindRecordingDir(QString filename)
{
// Not found in current group so try Default
StorageGroup sgroup("Default");
- QString tmpFile = sgroup.FindRecordingDir(filename);
+ QString tmpFile = sgroup.FindFileDir(filename);
result = (tmpFile.isEmpty()) ? result : tmpFile;
}
else
{
// Not found in Default so try any dir
StorageGroup sgroup;
- QString tmpFile = sgroup.FindRecordingDir(filename);
+ QString tmpFile = sgroup.FindFileDir(filename);
result = (tmpFile.isEmpty()) ? result : tmpFile;
}
View
8 mythtv/libs/libmythbase/storagegroup.h
@@ -24,7 +24,9 @@ class MBASE_PUBLIC StorageGroup
QStringList GetDirList(void) const
{ QStringList tmp = m_dirlist; tmp.detach(); return tmp; }
- QStringList GetFileList(QString Path);
+ QStringList GetDirFileList(QString dir, QString base,
+ bool recursive = false);
+ QStringList GetFileList(QString Path, bool recursive = false);
QStringList GetFileInfoList(QString Path);
bool FileExists(QString filename);
QStringList GetFileInfo(QString filename);
@@ -33,8 +35,8 @@ class MBASE_PUBLIC StorageGroup
const QString hostname = "",
QStringList *dirlist = NULL);
- QString FindRecordingFile(QString filename);
- QString FindRecordingDir(QString filename);
+ QString FindFile(QString filename);
+ QString FindFileDir(QString filename);
QString FindNextDirMostFree(void);
View
2  mythtv/libs/libmythmetadata/videometadata.cpp
@@ -964,7 +964,7 @@ QString VideoMetadata::VideoFileHash(const QString &file_name,
else if (!host.isEmpty())
{
StorageGroup sgroup("Videos", host);
- QString fullname = sgroup.FindRecordingFile(file_name);
+ QString fullname = sgroup.FindFile(file_name);
return FileHash(fullname);
}
else
View
2  mythtv/libs/libmythtv/previewgenerator.cpp
@@ -261,7 +261,7 @@ bool PreviewGenerator::Run(void)
if (lpath == outname)
{
StorageGroup sgroup;
- QString tmpFile = sgroup.FindRecordingFile(lpath);
+ QString tmpFile = sgroup.FindFile(lpath);
outname = (tmpFile.isEmpty()) ? outname : tmpFile;
}
View
120 mythtv/programs/mythbackend/httpconfig.cpp
@@ -1,7 +1,9 @@
// Qt headers
+#include <QByteArray>
#include <QDir>
#include <QFileInfo>
#include <QTextStream>
+#include <QUrl>
// MythTV headers
#include "httpconfig.h"
@@ -9,6 +11,7 @@
#include "mythcontext.h"
#include "mythdb.h"
#include "mythdirs.h"
+#include "storagegroup.h"
HttpConfig::HttpConfig() : HttpServerExtension("HttpConfig", QString())
{
@@ -145,51 +148,112 @@ bool HttpConfig::ProcessRequest(HttpWorkerThread*, HTTPRequest *request)
else if ((request->m_sMethod == "FileBrowser") &&
(request->m_mapParams.contains("dir")))
{
- QString startingDir = request->m_mapParams["dir"];
- bool dirsOnly = true;
- if (request->m_mapParams.contains("dirsOnly"))
- dirsOnly = request->m_mapParams["dirsOnly"].toInt();
-
- QDir dir(request->m_mapParams["dir"]);
- if (dir.exists())
+ QString startingDir = QUrl::fromPercentEncoding(request->m_mapParams["dir"].toUtf8());
+ if (startingDir.startsWith("myth://"))
{
- QTextStream os(&request->m_response);
- os << "<ul class=\"jqueryFileTree\" style=\"display: none;\">\r\n";
+ QUrl qurl(startingDir);
+ QString dir;
- QFileInfoList infoList = dir.entryInfoList();
- for (QFileInfoList::iterator it = infoList.begin();
- it != infoList.end();
- ++it )
- {
- QFileInfo &fi = *it;
- if (!fi.isDir())
- continue;
- if (fi.fileName().startsWith("."))
- continue;
+ QString host = qurl.host();
+ int port = qurl.port();
+
+ dir = qurl.path();
- os << " <li class=\"directory collapsed\"><a href=\"#\" rel=\""
- << fi.absoluteFilePath() << "/\">" << fi.fileName() << "</a></li>\r\n";
+ QString storageGroup = qurl.userName();
+
+ StorageGroup sgroup(storageGroup);
+ QStringList entries = sgroup.GetFileInfoList(dir);
+
+ if ((entries.size() == 1) &&
+ (entries[0].startsWith("sgdir::")))
+ {
+ QStringList parts = entries[0].split("::");
+ entries = sgroup.GetFileInfoList(parts[1]);
}
- if (!dirsOnly)
+ if (entries.size())
{
+ QTextStream os(&request->m_response);
+ os << "<ul class=\"jqueryFileTree\" style=\"display: none;\">\r\n";
+
+ for (QStringList::iterator it = entries.begin();
+ it != entries.end();
+ it++)
+ {
+ QString entry = *it;
+ QStringList parts = entry.split("::");
+ QFileInfo fi(parts[1]);
+ if (dir == "/")
+ dir = "";
+ QString path =
+ QString("myth://%1@%2%3%4").arg(storageGroup)
+ .arg(host).arg(dir).arg(parts[1]);
+ if (entry.startsWith("sgdir::"))
+ {
+ os << " <li class=\"directory collapsed\"><a href=\"#\" rel=\""
+ << path << "/\">" << parts[1] << "</a></li>\r\n";
+ }
+ else if (entry.startsWith("dir::"))
+ {
+ os << " <li class=\"directory collapsed\"><a href=\"#\" rel=\""
+ << path << "/\">" << fi.fileName() << "</a></li>\r\n";
+ }
+ else if (entry.startsWith("file::"))
+ {
+ os << " <li class=\"file ext_" << fi.suffix() << "\"><a href=\"#\" rel=\""
+ << parts[3] << "\">" << fi.fileName() << "</a></li>\r\n";
+ }
+ }
+ os << "</ul>\r\n";
+
+ handled = true;
+ }
+ } else {
+ QDir dir(startingDir);
+ if (dir.exists())
+ {
+ QTextStream os(&request->m_response);
+ os << "<ul class=\"jqueryFileTree\" style=\"display: none;\">\r\n";
+
+ QFileInfoList infoList = dir.entryInfoList();
for (QFileInfoList::iterator it = infoList.begin();
it != infoList.end();
++it )
{
QFileInfo &fi = *it;
- if (fi.isDir())
+ if (!fi.isDir())
continue;
if (fi.fileName().startsWith("."))
continue;
- os << " <li class=\"file ext_" << fi.suffix() << "\"><a href=\"#\" rel=\""
- << fi.fileName() << "\">" << fi.fileName() << "</a></li>\r\n";
+ os << " <li class=\"directory collapsed\"><a href=\"#\" rel=\""
+ << fi.absoluteFilePath() << "/\">" << fi.fileName() << "</a></li>\r\n";
}
- }
- os << "</ul>\r\n";
- handled = true;
+ bool dirsOnly = true;
+ if (request->m_mapParams.contains("dirsOnly"))
+ dirsOnly = request->m_mapParams["dirsOnly"].toInt();
+
+ if (!dirsOnly)
+ {
+ for (QFileInfoList::iterator it = infoList.begin();
+ it != infoList.end();
+ ++it )
+ {
+ QFileInfo &fi = *it;
+ if (fi.isDir())
+ continue;
+ if (fi.fileName().startsWith("."))
+ continue;
+
+ os << " <li class=\"file ext_" << fi.suffix() << "\"><a href=\"#\" rel=\""
+ << fi.absoluteFilePath() << "\">" << fi.fileName() << "</a></li>\r\n";
+ }
+ }
+ os << "</ul>\r\n";
+
+ handled = true;
+ }
}
}
else if ((request->m_sMethod == "GetValueList") &&
View
10 mythtv/programs/mythbackend/mainserver.cpp
@@ -1963,7 +1963,7 @@ void MainServer::DeleteRecordedFiles(const DeleteStruct *ds)
.arg(logInfo).arg(query.value(0).toString()));
StorageGroup sgroup(storagegroup);
- QString localFile = sgroup.FindRecordingFile(basename);
+ QString localFile = sgroup.FindFile(basename);
QString url = QString("myth://%1@%2:%3/%4").arg(storagegroup)
.arg(gCoreContext->GetSettingOnHost("BackendServerIP", hostname))
.arg(gCoreContext->GetSettingOnHost("BackendServerPort", hostname))
@@ -2895,7 +2895,7 @@ void MainServer::HandleQueryFileHash(QStringList &slist, PlaybackSock *pbs)
StorageGroup sgroup(storageGroup, gCoreContext->GetHostName());
- QString fullname = sgroup.FindRecordingFile(filename);
+ QString fullname = sgroup.FindFile(filename);
QString hash = FileHash(fullname);
retlist << hash;
@@ -2932,7 +2932,7 @@ void MainServer::HandleQueryFileExists(QStringList &slist, PlaybackSock *pbs)
StorageGroup sgroup(storageGroup, gCoreContext->GetHostName());
- QString fullname = sgroup.FindRecordingFile(filename);
+ QString fullname = sgroup.FindFile(filename);
if (!fullname.isEmpty())
{
@@ -4538,7 +4538,7 @@ bool MainServer::HandleDeleteFile(QString filename, QString storagegroup,
return false;
}
- QString fullfile = sgroup.FindRecordingFile(filename);
+ QString fullfile = sgroup.FindFile(filename);
if (fullfile.isEmpty()) {
VERBOSE(VB_IMPORTANT, QString("Unable to find %1 in HandleDeleteFile()")
@@ -5876,7 +5876,7 @@ QString MainServer::LocalFilePath(const QUrl &url, const QString &wantgroup)
lpath = QFileInfo(lpath).fileName();
}
- QString tmpFile = sgroup.FindRecordingFile(lpath);
+ QString tmpFile = sgroup.FindFile(lpath);
if (!tmpFile.isEmpty())
{
lpath = tmpFile;
View
6 mythtv/programs/mythbackend/services/content.cpp
@@ -63,7 +63,7 @@ QFileInfo Content::GetFile( const QString &sStorageGroup, const QString &sFileNa
// ------------------------------------------------------------------
StorageGroup storage( sGroup );
- QString sFullFileName = storage.FindRecordingFile( sFileName );
+ QString sFullFileName = storage.FindFile( sFileName );
if (sFullFileName.isEmpty())
{
@@ -103,7 +103,7 @@ QStringList Content::GetFileList( const QString &sStorageGroup )
StorageGroup sgroup(sStorageGroup);
- return sgroup.GetFileList("");
+ return sgroup.GetFileList("", true);
}
/////////////////////////////////////////////////////////////////////////////
@@ -531,7 +531,7 @@ QString Content::GetHash( const QString &sStorageGroup, const QString &sFileName
StorageGroup sgroup(storageGroup, gCoreContext->GetHostName());
- QString fullname = sgroup.FindRecordingFile(sFileName);
+ QString fullname = sgroup.FindFile(sFileName);
QString hash = FileHash(fullname);
if (hash == "NULL")
View
2  mythtv/programs/mythbackend/upnpcdstv.cpp
@@ -372,7 +372,7 @@ void UPnpCDSTv::AddItem( const UPnpCDSRequest *pRequest,
// ----------------------------------------------------------------------
StorageGroup sg(sStorageGrp, sHostName);
- QString sFilePath = sg.FindRecordingFile(sBaseName);
+ QString sFilePath = sg.FindFile(sBaseName);
QString sMimeType;
if ( QFile::exists(sFilePath) )
View
2  mythtv/programs/mythbackend/upnpcdsvideo.cpp
@@ -350,7 +350,7 @@ void UPnpCDSVideo::AddItem( const UPnpCDSRequest *pRequest,
if (!QFile::exists( sFullFileName ))
{
StorageGroup sgroup("Videos");
- sFullFileName = sgroup.FindRecordingFile( sFullFileName );
+ sFullFileName = sgroup.FindFile( sFullFileName );
}
QFileInfo fInfo( sFullFileName );
Please sign in to comment.
Something went wrong with that request. Please try again.