Skip to content

Commit

Permalink
StorageGroup method renames, enhancements, and HTML Setup helper
Browse files Browse the repository at this point in the history
- 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
cpinkham committed Apr 14, 2011
1 parent 4cba1a3 commit 7255d46
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 66 deletions.
2 changes: 1 addition & 1 deletion mythtv/libs/libmyth/programinfo.cpp
Expand Up @@ -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())
{
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythbase/mythversion.h
Expand Up @@ -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.
*
Expand Down
84 changes: 63 additions & 21 deletions mythtv/libs/libmythbase/storagegroup.cpp
Expand Up @@ -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";

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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 == "/")
Expand All @@ -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;
}
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -307,7 +349,7 @@ QStringList StorageGroup::GetFileInfo(QString filename)
if (!FileExists(filename))
{
searched = true;
filename = FindRecordingFile(filename);
filename = FindFile(filename);
}

if ((searched && !filename.isEmpty()) ||
Expand Down Expand Up @@ -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("");
Expand All @@ -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())
Expand All @@ -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;
}

Expand Down
8 changes: 5 additions & 3 deletions mythtv/libs/libmythbase/storagegroup.h
Expand Up @@ -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);
Expand All @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythmetadata/videometadata.cpp
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/previewgenerator.cpp
Expand Up @@ -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;
}

Expand Down
120 changes: 92 additions & 28 deletions mythtv/programs/mythbackend/httpconfig.cpp
@@ -1,14 +1,17 @@
// Qt headers
#include <QByteArray>
#include <QDir>
#include <QFileInfo>
#include <QTextStream>
#include <QUrl>

// MythTV headers
#include "httpconfig.h"
#include "backendutil.h"
#include "mythcontext.h"
#include "mythdb.h"
#include "mythdirs.h"
#include "storagegroup.h"

HttpConfig::HttpConfig() : HttpServerExtension("HttpConfig", QString())
{
Expand Down Expand Up @@ -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") &&
Expand Down

0 comments on commit 7255d46

Please sign in to comment.