Skip to content

Commit

Permalink
Merge pull request #691 from overte-org/fix/file_api
Browse files Browse the repository at this point in the history
Remove File API and limit audio recording file location
  • Loading branch information
ksuprynowicz authored Nov 1, 2023
2 parents 894f8ce + bf8ad07 commit 5f0635e
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 175 deletions.
22 changes: 0 additions & 22 deletions interface/resources/qml/hifi/+webengine/DesktopWebEngine.qml
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,5 @@ Item {


function initWebviewProfileHandlers(profile) {
downloadUrl = currentUrl;
if (webViewProfileSetup) return;
webViewProfileSetup = true;

profile.downloadRequested.connect(function(download){
adaptedPath = File.convertUrlToPath(downloadUrl);
tempDir = File.getTempDir();
download.path = tempDir + "/" + adaptedPath;
download.accept();
if (download.state === WebEngineDownloadItem.DownloadInterrupted) {
console.log("download failed to complete");
}
})

profile.downloadFinished.connect(function(download){
if (download.state === WebEngineDownloadItem.DownloadCompleted) {
File.runUnzip(download.path, downloadUrl, autoAdd);
} else {
console.log("The download was corrupted, state: " + download.state);
}
autoAdd = false;
})
}
}
5 changes: 2 additions & 3 deletions interface/src/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@
#include <EntityScriptServerLogClient.h>
#include <EntityScriptingInterface.h>
#include <ErrorDialog.h>
#include <FileScriptingInterface.h>
#include <Finally.h>
#include <FingerprintUtils.h>
#include <FramebufferCache.h>
Expand Down Expand Up @@ -3414,9 +3413,9 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
surfaceContext->setContextProperty("Controller", DependencyManager::get<controller::ScriptingInterface>().data());
surfaceContext->setContextProperty("Entities", DependencyManager::get<EntityScriptingInterface>().data());
surfaceContext->setContextProperty("Performance", new PerformanceScriptingInterface());
_fileDownload = new FileScriptingInterface(engine);
_fileDownload = new ArchiveDownloadInterface(engine);
surfaceContext->setContextProperty("File", _fileDownload);
connect(_fileDownload, &FileScriptingInterface::unzipResult, this, &Application::handleUnzip);
connect(_fileDownload, &ArchiveDownloadInterface::unzipResult, this, &Application::handleUnzip);
surfaceContext->setContextProperty("MyAvatar", getMyAvatar().get());
surfaceContext->setContextProperty("Messages", DependencyManager::get<MessagesClient>().data());
surfaceContext->setContextProperty("Recording", DependencyManager::get<RecordingScriptingInterface>().data());
Expand Down
6 changes: 3 additions & 3 deletions interface/src/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#include <AbstractViewStateInterface.h>
#include <EntityEditPacketSender.h>
#include <EntityTreeRenderer.h>
#include <FileScriptingInterface.h>
#include "ArchiveDownloadInterface.h"
#include <input-plugins/KeyboardMouseDevice.h>
#include <input-plugins/TouchscreenDevice.h>
#include <input-plugins/TouchscreenVirtualPadDevice.h>
Expand Down Expand Up @@ -425,7 +425,7 @@ public slots:

void handleUnzip(QString sourceFile, QStringList destinationFile, bool autoAdd, bool isZip, bool isBlocks);

FileScriptingInterface* getFileDownloadInterface() { return _fileDownload; }
ArchiveDownloadInterface* getFileDownloadInterface() { return _fileDownload; }

void handleLocalServerConnection() const;
void readArgumentsFromLocalSocket() const;
Expand Down Expand Up @@ -820,7 +820,7 @@ private slots:
QTimer _addAssetToWorldErrorTimer;
mutable QTimer _entityServerConnectionTimer;

FileScriptingInterface* _fileDownload;
ArchiveDownloadInterface* _fileDownload;
AudioInjectorPointer _snapshotSoundInjector;
SharedSoundPointer _snapshotSound;
SharedSoundPointer _sampleSound;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
//
// FileScriptingInterface.cpp
// ArchiveDownloadInterface.cpp
// libraries/script-engine/src
//
// Created by Elisa Lupin-Jimenez on 6/28/16.
// Copyright 2016 High Fidelity, Inc.
// Copyright 2023 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//

#include "FileScriptingInterface.h"
#include "ArchiveDownloadInterface.h"

#include <QtCore/QTemporaryDir>
#include <QtCore/QDir>
Expand All @@ -33,11 +34,11 @@
#include "ScriptEngineLogging.h"


FileScriptingInterface::FileScriptingInterface(QObject* parent) : QObject(parent) {
ArchiveDownloadInterface::ArchiveDownloadInterface(QObject* parent) : QObject(parent) {
// nothing for now
}

void FileScriptingInterface::runUnzip(QString path, QUrl url, bool autoAdd, bool isZip, bool isBlocks) {
void ArchiveDownloadInterface::runUnzip(QString path, QUrl url, bool autoAdd, bool isZip, bool isBlocks) {
QString fileName = "/" + path.section("/", -1);
QString tempDir = path;
if (!isZip) {
Expand Down Expand Up @@ -71,7 +72,7 @@ void FileScriptingInterface::runUnzip(QString path, QUrl url, bool autoAdd, bool

}

QStringList FileScriptingInterface::unzipFile(QString path, QString tempDir) {
QStringList ArchiveDownloadInterface::unzipFile(QString path, QString tempDir) {
#if defined(Q_OS_ANDROID)
// FIXME quazip hasn't been built on the android toolchain
return QStringList();
Expand All @@ -94,7 +95,7 @@ QStringList FileScriptingInterface::unzipFile(QString path, QString tempDir) {
}

// fix to check that we are only referring to a temporary directory
bool FileScriptingInterface::isTempDir(QString tempDir) {
bool ArchiveDownloadInterface::isTempDir(QString tempDir) {
QString folderName = "/" + tempDir.section("/", -1);
QString tempContainer = tempDir;
tempContainer.remove(folderName);
Expand All @@ -106,7 +107,7 @@ bool FileScriptingInterface::isTempDir(QString tempDir) {
return (testContainer == tempContainer);
}

bool FileScriptingInterface::hasModel(QStringList fileList) {
bool ArchiveDownloadInterface::hasModel(QStringList fileList) {
for (int i = 0; i < fileList.size(); i++) {
if (fileList.at(i).toLower().contains(".fbx") || fileList.at(i).toLower().contains(".obj")) {
return true;
Expand All @@ -115,33 +116,33 @@ bool FileScriptingInterface::hasModel(QStringList fileList) {
return false;
}

QString FileScriptingInterface::getTempDir() {
QString ArchiveDownloadInterface::getTempDir() {
QTemporaryDir dir;
dir.setAutoRemove(false);
return dir.path();
// do something to delete this temp dir later
}

QString FileScriptingInterface::convertUrlToPath(QUrl url) {
QString ArchiveDownloadInterface::convertUrlToPath(QUrl url) {
QString newUrl;
QString oldUrl = url.toString();
newUrl = oldUrl.section("filename=", 1, 1);
return newUrl;
}

// this function is not in use
void FileScriptingInterface::downloadZip(QString path, const QString link) {
void ArchiveDownloadInterface::downloadZip(QString path, const QString link) {
QUrl url = QUrl(link);
auto request = DependencyManager::get<ResourceManager>()->createResourceRequest(
nullptr, url, true, -1, "FileScriptingInterface::downloadZip");
nullptr, url, true, -1, "ArchiveDownloadInterface::downloadZip");
connect(request, &ResourceRequest::finished, this, [this, path]{
unzipFile(path, ""); // so intellisense isn't mad
});
request->send();
}

// this function is not in use
void FileScriptingInterface::recursiveFileScan(QFileInfo file, QString* dirName) {
void ArchiveDownloadInterface::recursiveFileScan(QFileInfo file, QString* dirName) {
/*if (!file.isDir()) {
return;
}*/
Expand Down
106 changes: 106 additions & 0 deletions interface/src/ArchiveDownloadInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//
// ArchiveDownloadInterface.h
// libraries/script-engine/src
//
// Created by Elisa Lupin-Jimenez on 6/28/16.
// Copyright 2016 High Fidelity, Inc.
// Copyright 2023 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//

/// @addtogroup Interface
/// @{

#ifndef hifi_ArchiveDownloadInterface_h
#define hifi_ArchiveDownloadInterface_h

#include <QtCore/QObject>
#include <QtCore/QUrl>
#include <QFileInfo>
#include <QString>

/**
* @brief The ArchiveDownloadInterface API provides some facilities for working with the file system.
*/
class ArchiveDownloadInterface : public QObject {
Q_OBJECT

public:
ArchiveDownloadInterface(QObject* parent);

public slots:

/**
* @brief Extracts a filename from a URL, where the filename is specified in the query part of the URL as filename=.
* @param url - The URL to extract the filename from.
* @return The filename specified in the URL; an empty string if no filename is specified.
*/
QString convertUrlToPath(QUrl url);

/**
* @brief Unzips a file in the local file system to a new, unique temporary directory.
* @param path - The path of the zip file in the local file system. May have a leading "file:///".
* Need not have a ".zip" extension if it is in a temporary directory (as created by
* getTempDir).
* @param url - Not used.
* @param autoAdd - Not used by user scripts. The value is simply passed through to the
* unzipResult signal.
* @param isZip - Set to true if path has a ".zip" extension,
* false if it doesn't (but should still be treated as a zip file).
* @param isBlocks - Not used by user scripts. The value is simply passed through to the
* unzipResult signal.
* @example (Old example from JS, needs to be converted)
* Select and unzip a file.
* File.unzipResult.connect(function (zipFile, unzipFiles, autoAdd, isZip, isBlocks) {
* print("File.unzipResult()");
* print("- zipFile: " + zipFile);
* print("- unzipFiles(" + unzipFiles.length + "): " + unzipFiles);
* print("- autoAdd: " + autoAdd);
* print("- isZip: " + isZip);
* print("- isBlocks: " + isBlocks);
* });
*
* var zipFile = Window.browse("Select a Zip File", "", "*.zip");
* if (zipFile) {
* File.runUnzip(zipFile, "", false, true, false);
* } else {
* print("Zip file not selected.");
* }
*/
void runUnzip(QString path, QUrl url, bool autoAdd, bool isZip, bool isBlocks);

/**
* Creates a new, unique directory for temporary use.
* @return The path of the newly created temporary directory.
*/
QString getTempDir();

signals:

/**
* Triggered when runUnzip completes.
* @param zipFile - The file that was unzipped.
* @param unzipFiles - The paths of the unzipped files in a newly created temporary directory. Includes entries
* for any subdirectories created. An empty array if the zipFile could not be unzipped.
* @param autoAdd - The value that runUnzip was called with.
* @param isZip - true if runUnzip was called with isZip == true,
* unless there is no FBX or OBJ file in the unzipped file(s) in which case the value is false.
* @param isBlocks - The value that runUnzip was called with.
*/
void unzipResult(QString zipFile, QStringList unzipFile, bool autoAdd, bool isZip, bool isBlocks);

private:
bool isTempDir(QString tempDir);
bool hasModel(QStringList fileList);
QStringList unzipFile(QString path, QString tempDir);
void recursiveFileScan(QFileInfo file, QString* dirName);
void downloadZip(QString path, const QString link);

};

#endif // hifi_ArchiveDownloadInterface_h

/// @}
18 changes: 15 additions & 3 deletions interface/src/scripting/Audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include "AudioClient.h"
#include "AudioHelpers.h"
#include "ui/AvatarInputs.h"
#include "ui/Snapshot.h"
#include "AccountManager.h"

using namespace scripting;

Expand Down Expand Up @@ -58,9 +60,19 @@ Audio::Audio() : _devices(_contextIsHMD) {
onContextChanged();
}

bool Audio::startRecording(const QString& filepath) {
return resultWithWriteLock<bool>([&] {
return DependencyManager::get<AudioClient>()->startRecording(filepath);
QUuid Audio::startRecording() {
return resultWithWriteLock<QUuid>([&] {
const QString FILENAME_PREFIX = "overte-audio-";
const QString AUDIO_FORMAT = "wav";
QUuid id = QUuid::createUuid();

QString filepath = DependencyManager::get<Snapshot>()->_snapshotsLocation.get();
QString filename = FILENAME_PREFIX + id.toString() + "." + AUDIO_FORMAT;
if (DependencyManager::get<AudioClient>()->startRecording(filepath + "/" + filename)) {
return id;
} else {
return QUuid();
}
});
}

Expand Down
16 changes: 7 additions & 9 deletions interface/src/scripting/Audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,24 +295,22 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable {

/*@jsdoc
* Starts making an audio recording of the audio being played in-world (i.e., not local-only audio) to a file in WAV format.
* Audio is recorded to snapshots directory specified in settings.
* @function Audio.startRecording
* @param {string} filename - The path and name of the file to make the recording in. Should have a <code>.wav</code>
* extension. The file is overwritten if it already exists.
* @returns {boolean} <code>true</code> if the specified file could be opened and audio recording has started, otherwise
* <code>false</code>.
* @returns {Uuid} A valid <code>Uuid</code> if the specified file could be opened and audio recording has started, otherwise
* <code>Uuid.NULL</code>.
* @example <caption>Make a 10 second audio recording.</caption>
* var filename = File.getTempDir() + "/audio.wav";
* if (Audio.startRecording(filename)) {
* if (Audio.startRecording() !== Uuid.NULL) {
* Script.setTimeout(function () {
* Audio.stopRecording();
* print("Audio recording made in: " + filename);
* print("Audio recording finished.");
* }, 10000);
*
* } else {
* print("Could not make an audio recording in: " + filename);
* print("Could not make an audio recording file.");
* }
*/
Q_INVOKABLE bool startRecording(const QString& filename);
Q_INVOKABLE QUuid startRecording();

/*@jsdoc
* Finishes making an audio recording started with {@link Audio.startRecording|startRecording}.
Expand Down
Loading

0 comments on commit 5f0635e

Please sign in to comment.