Skip to content

Commit 551eb30

Browse files
Browser sources include entire parent directory tree. (#33)
1 parent d6c7b4d commit 551eb30

File tree

5 files changed

+155
-13
lines changed

5 files changed

+155
-13
lines changed

buildspec.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
"name": "elgato-marketplace-connect",
4040
"displayName": "Elgato Marketplace Connect",
4141
"versionMajor": 1,
42-
"versionMinor": 0,
43-
"versionPatch": 2,
42+
"versionMinor": 1,
43+
"versionPatch": 0,
4444
"buildNumber": 0,
4545
"releaseType": "release",
4646
"author": "Elgato",

src/export-wizard.cpp

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ with this program. If not, see <https://www.gnu.org/licenses/>
1818

1919
#include <algorithm>
2020

21+
#include <util/platform.h>
22+
2123
#include "export-wizard.hpp"
2224
#include "elgato-styles.hpp"
2325
#include "plugins.hpp"
26+
#include "plugin-support.h"
2427
#include <QMainWindow>
2528
#include <QVBoxLayout>
2629
#include <QPushButton>
@@ -52,9 +55,7 @@ const std::vector<std::string> ExcludedModules{
5255
"obs-outputs.dll", "obs-nvenc.dll", "obs-filters.dll", "obs-ffmpeg.dll",
5356
"obs-browser.dll", "nv-filters.dll", "image-source.dll",
5457
"frontend-tools.dll", "decklink-output-ui.dll", "decklink-captions.dll",
55-
"coreaudio-encoder.dll",
56-
// This plugin
57-
"elgato-marketplace.dll"};
58+
"coreaudio-encoder.dll", "elgato-marketplace.dll"};
5859

5960
FileCollectionCheck::FileCollectionCheck(QWidget *parent,
6061
std::vector<std::string> files)
@@ -80,8 +81,30 @@ FileCollectionCheck::FileCollectionCheck(QWidget *parent,
8081
layout->addWidget(subTitle);
8182

8283
auto fileList = new QListWidget(this);
84+
std::vector<std::string> browserSourceDirs;
85+
8386
for (auto fileName : _files) {
84-
fileList->addItem(fileName.c_str());
87+
bool hasExtension = fileName.rfind(".") != std::string::npos;
88+
std::string extension =
89+
hasExtension ? os_get_path_extension(fileName.c_str())
90+
: "";
91+
if (extension == ".html" || extension == ".htm") {
92+
if (fileName.rfind("/") == std::string::npos) {
93+
obs_log(LOG_INFO, "Error exporting file- could not determine parent directory of file.");
94+
continue;
95+
}
96+
std::string parentDir = fileName.substr(0, fileName.rfind("/"));
97+
if (std::find(browserSourceDirs.begin(), browserSourceDirs.end(), parentDir) == browserSourceDirs.end()) {
98+
browserSourceDirs.push_back(parentDir);
99+
std::vector<std::string> parentDirFiles;
100+
_SubFiles(parentDirFiles, parentDir);
101+
for (auto parentFileName : parentDirFiles) {
102+
fileList->addItem(parentFileName.c_str());
103+
}
104+
}
105+
} else {
106+
fileList->addItem(fileName.c_str());
107+
}
85108
}
86109

87110
fileList->setStyleSheet(EListStyle);
@@ -106,6 +129,40 @@ FileCollectionCheck::FileCollectionCheck(QWidget *parent,
106129
layout->addLayout(buttons);
107130
}
108131

132+
bool FileCollectionCheck::_SubFiles(std::vector<std::string>& files, std::string curDir)
133+
{
134+
os_dir_t* dir = os_opendir(curDir.c_str());
135+
if (dir) {
136+
struct os_dirent* ent;
137+
for (;;) {
138+
ent = os_readdir(dir);
139+
if (!ent)
140+
break;
141+
if (ent->directory) {
142+
std::string dName = ent->d_name;
143+
if (dName == "." || dName == "..") {
144+
continue;
145+
}
146+
std::string dPath = curDir + "/" + dName;
147+
if (!_SubFiles(files, dPath)) {
148+
os_closedir(dir);
149+
return false;
150+
}
151+
} else {
152+
std::string filename = ent->d_name;
153+
std::string filePath = curDir + "/" + filename;
154+
files.push_back(filePath);
155+
}
156+
}
157+
} else {
158+
obs_log(LOG_ERROR, "Fatal: Could not open directory: %s",
159+
curDir.c_str());
160+
return false;
161+
}
162+
os_closedir(dir);
163+
return true;
164+
}
165+
109166
VideoSourceLabels::VideoSourceLabels(QWidget *parent,
110167
std::map<std::string, std::string> devices)
111168
: QWidget(parent)

src/export-wizard.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class FileCollectionCheck : public QWidget {
5151

5252
private:
5353
std::vector<std::string> _files;
54+
bool _SubFiles(std::vector<std::string>& files, std::string curDir);
5455
};
5556

5657
class VideoSourceLabels : public QWidget {

src/scene-bundle.cpp

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
2828
#include <QMetaObject>
2929
#include <vector>
3030
#include <string>
31+
#include <filesystem>
3132
#include <stdio.h>
3233
#include <algorithm>
3334
#include <zip_file.hpp>
@@ -46,7 +47,10 @@ const std::map<std::string, std::string> extensionMap{
4647
{".mkv", "/video/"}, {".mp3", "/audio/"},
4748
{".wav", "/aduio/"}, {".effect", "/shaders/"},
4849
{".shader", "/shaders/"}, {".hlsl", "/shaders/"},
49-
{".lua", "/scripts/"}, {".py", "/scripts/"}};
50+
{".lua", "/scripts/"}, {".py", "/scripts/"},
51+
{".html", "/browser-sources/"},
52+
{".htm", "/browser-sources/"}
53+
};
5054

5155
// Filter IDs of incompatible filter types, e.g. filters
5256
// that require external libraries or executables.
@@ -305,11 +309,26 @@ SceneBundleStatus SceneBundle::ToElgatoCloudFile(
305309
std::string collection_json = _collection.dump(2);
306310
std::string bundleInfo_json = bundleInfo.dump(2);
307311

312+
std::vector<std::string> browserSourceDirs;
313+
308314
ecFile.writestr("collection.json", collection_json);
309315
ecFile.writestr("bundle_info.json", bundleInfo_json);
310316
// Write all assets to zip archive.
311317
for (const auto &file : _fileMap) {
312318
std::string oFilename = file.first;
319+
320+
std::string filename = oFilename.substr(oFilename.rfind("/") + 1);
321+
std::string parentDir = oFilename.substr(0, oFilename.rfind("/"));
322+
std::string zipParent = file.second.substr(0, file.second.rfind("/"));
323+
bool hasExtension = filename.rfind(".") != std::string::npos;
324+
std::string extension =
325+
hasExtension ? os_get_path_extension(oFilename.c_str())
326+
: "";
327+
bool isBrowserSource = extension == ".html" || extension == ".htm";
328+
bool addBrowser = isBrowserSource && std::find(browserSourceDirs.begin(), browserSourceDirs.end(), parentDir) == browserSourceDirs.end();
329+
if (addBrowser) {
330+
browserSourceDirs.push_back(parentDir);
331+
}
313332
struct stat st;
314333
os_stat(oFilename.c_str(), &st);
315334
if ((st.st_mode & S_IFMT) == S_IFDIR) {
@@ -322,13 +341,24 @@ SceneBundleStatus SceneBundle::ToElgatoCloudFile(
322341
}
323342
return SceneBundleStatus::Error;
324343
}
325-
} else if (!_AddFileToZip(file.first, file.second, ecFile)) {
326-
bool wasInterrupted = _interrupt;
327-
_interrupt = false;
328-
if (wasInterrupted) {
329-
return _interruptReason;
344+
} else if (addBrowser) {
345+
if (!_AddBrowserSourceContentsToZip(parentDir, zipParent, ecFile)) {
346+
bool wasInterrupted = _interrupt;
347+
_interrupt = false;
348+
if (wasInterrupted) {
349+
return _interruptReason;
350+
}
351+
return SceneBundleStatus::Error;
352+
}
353+
} else if(!isBrowserSource) {
354+
if (!_AddFileToZip(file.first, file.second, ecFile)) {
355+
bool wasInterrupted = _interrupt;
356+
_interrupt = false;
357+
if (wasInterrupted) {
358+
return _interruptReason;
359+
}
360+
return SceneBundleStatus::Error;
330361
}
331-
return SceneBundleStatus::Error;
332362
}
333363
}
334364

@@ -505,6 +535,13 @@ void SceneBundle::_CreateFileMap(nlohmann::json &item)
505535
} else {
506536
directory = "/misc/";
507537
}
538+
bool isBrowserSource = extension == ".htm" || extension == ".html";
539+
if (isBrowserSource) {
540+
std::filesystem::path pathObj(value);
541+
auto parentPath = pathObj.parent_path();
542+
std::string parent = parentPath.filename().string();
543+
directory += parent + "/";
544+
}
508545
std::string newFileName = "Assets" + directory + filename;
509546
auto result =
510547
std::find_if(std::begin(_fileMap), std::end(_fileMap),
@@ -538,6 +575,51 @@ bool SceneBundle::_AddFileToZip(std::string filePath, std::string zipPath,
538575
return true;
539576
}
540577

578+
bool SceneBundle::_AddBrowserSourceContentsToZip(std::string dirPath, std::string zipDir,
579+
miniz_cpp::zip_file& ecFile)
580+
{
581+
// Iterate the files in the directory and add them to the zip.
582+
// Ignore sub-directories
583+
os_dir_t* dir = os_opendir(dirPath.c_str());
584+
if (dir) {
585+
struct os_dirent* ent;
586+
for (;;) {
587+
ent = os_readdir(dir);
588+
if (!ent)
589+
break;
590+
if (ent->directory) {
591+
std::string dName = ent->d_name;
592+
if (dName == "." || dName == "..") {
593+
continue;
594+
}
595+
std::string dPath = dirPath + "/" + dName;
596+
std::string zipDPath = zipDir + "/" + dName;
597+
if (!_AddBrowserSourceContentsToZip(dPath, zipDPath, ecFile)) {
598+
os_closedir(dir);
599+
return false;
600+
}
601+
} else {
602+
std::string filename = ent->d_name;
603+
std::string filePath = dirPath + "/" + filename;
604+
std::string zipFilePath = zipDir + "/" + filename;
605+
if (!_AddFileToZip(filePath, zipFilePath, ecFile)) {
606+
os_closedir(dir);
607+
return false;
608+
}
609+
}
610+
}
611+
}
612+
else {
613+
obs_log(LOG_ERROR, "Fatal: Could not open directory: %s",
614+
dirPath.c_str());
615+
return false;
616+
}
617+
618+
os_closedir(dir);
619+
620+
return true;
621+
}
622+
541623
bool SceneBundle::_AddDirContentsToZip(std::string dirPath, std::string zipDir,
542624
miniz_cpp::zip_file &ecFile)
543625
{

src/scene-bundle.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class SceneBundle {
9393
miniz_cpp::zip_file &ecFile);
9494
bool _AddDirContentsToZip(std::string dirPath, std::string zipDir,
9595
miniz_cpp::zip_file &ecFile);
96+
bool _AddBrowserSourceContentsToZip(std::string dirPath, std::string zipDir,
97+
miniz_cpp::zip_file& ecFile);
9698
void _reset();
9799
};
98100

0 commit comments

Comments
 (0)