summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--GUI/GUI/GUI/Frame.cpp116
-rw-r--r--GUI/GUI/GUI/Frame.h11
-rw-r--r--GUI/GUI/GUI/GUI.vcxproj2
-rw-r--r--GUI/GUI/GUI/GUI.vcxproj.filters14
-rw-r--r--GUI/GUI/GUI/PythonWrapper.cpp54
-rw-r--r--GUI/GUI/GUI/PythonWrapper.h28
-rw-r--r--GUI/package.ps11
-rw-r--r--Python/python310._pth5
-rw-r--r--Scripts/emotes.py (renamed from emotes.py)0
-rw-r--r--Scripts/generate_fonts.py (renamed from generate_fonts.py)0
-rw-r--r--Scripts/generate_params.py (renamed from generate_params.py)0
-rw-r--r--Scripts/generate_utils.py (renamed from generate_utils.py)0
-rw-r--r--Scripts/libtastt.py (renamed from libtastt.py)0
-rw-r--r--Scripts/libunity.py (renamed from libunity.py)0
-rw-r--r--Scripts/obfuscate.py (renamed from obfuscate.py)0
-rw-r--r--Scripts/osc_ctrl.py (renamed from osc_ctrl.py)0
-rw-r--r--Scripts/steamvr.py (renamed from steamvr.py)0
-rw-r--r--Scripts/string_matcher.py (renamed from string_matcher.py)0
-rw-r--r--Scripts/transcribe.py (renamed from transcribe.py)0
19 files changed, 212 insertions, 19 deletions
diff --git a/GUI/GUI/GUI/Frame.cpp b/GUI/GUI/GUI/Frame.cpp
index 841bfb9..74683ca 100644
--- a/GUI/GUI/GUI/Frame.cpp
+++ b/GUI/GUI/GUI/Frame.cpp
@@ -1,23 +1,44 @@
#include "Frame.h"
+#include "PythonWrapper.h"
#include <filesystem>
+#include <string>
+#include <vector>
+
+namespace {
+ enum FrameIds {
+ ID_PY_PANEL,
+ ID_PY_VERSION_BUTTON,
+ ID_PY_SETUP_BUTTON,
+ ID_PY_OUT,
+ };
+};
Frame::Frame()
- : wxFrame(nullptr, wxID_ANY, "TaSTT")
+ : wxFrame(nullptr, wxID_ANY, "TaSTT"),
+ py_panel_(this, ID_PY_PANEL),
+ py_panel_sizer_(wxVERTICAL),
+ py_version_button_(&py_panel_, ID_PY_VERSION_BUTTON, "Check embedded Python version"),
+ py_setup_button_(&py_panel_, ID_PY_SETUP_BUTTON, "Set up Python virtual environment"),
+ py_out_(&py_panel_, ID_PY_OUT, wxEmptyString, wxDefaultPosition,
+ wxSize(/*x_px=*/480, /*y_px=*/160), wxTE_MULTILINE)
{
- Bind(wxEVT_MENU, &Frame::OnExit, this, wxID_EXIT);
+ Bind(wxEVT_MENU, &Frame::OnExit, this, wxID_EXIT);
+ Bind(wxEVT_BUTTON, &Frame::OnGetPythonVersion, this, ID_PY_VERSION_BUTTON);
+ Bind(wxEVT_BUTTON, &Frame::OnSetupPython, this, ID_PY_SETUP_BUTTON);
- // wx needs this to be able to load PNGs.
- wxImage::AddHandler(&png_handler_);
+ // wx needs this to be able to load PNGs.
+ wxImage::AddHandler(&png_handler_);
+ const std::string icon_path = "Resources/logo.png";
+ LoadAndSetIcon(icon_path);
- const std::string logo_path = "Resources/logo.png";
- if (!std::filesystem::exists(logo_path)) {
- wxLogFatalError("Logo is missing from %s", logo_path.c_str());
- }
- wxBitmap icon_img("Resources/logo.png", wxBITMAP_TYPE_PNG);
- wxIcon icon;
- icon.CopyFromBitmap(icon_img);
- SetIcon(icon);
+ wxSize py_out_size(/*x=*/80, /*y=*/20);
+ py_out_.SetSize(py_out_size);
+
+ py_panel_.SetSizer(&py_panel_sizer_);
+ py_panel_sizer_.Add(&py_version_button_);
+ py_panel_sizer_.Add(&py_setup_button_);
+ py_panel_sizer_.Add(&py_out_);
}
void Frame::OnExit(wxCommandEvent& event)
@@ -25,3 +46,74 @@ void Frame::OnExit(wxCommandEvent& event)
Close(true);
}
+void Frame::OnGetPythonVersion(wxCommandEvent& event)
+{
+ PythonWrapper py;
+ std::string py_version = py.GetVersion();
+ py_out_.AppendText(py_version + "\n");
+}
+
+void Frame::OnSetupPython(wxCommandEvent& event)
+{
+ PythonWrapper py;
+
+ py_out_.AppendText("Setting up Python virtual environment\n");
+ py_out_.AppendText("This could take several minutes, please be patient!\n");
+ py_out_.AppendText("This will download ~5GB of dependencies.\n");
+ py_out_.AppendText("Dependencies are installed in the executable folder, "
+ "so deleting the folder is all that's needed to undo this.");
+
+ {
+ std::string py_out;
+ std::ostringstream py_out_oss;
+ py_out_oss << "Installing pip" << std::endl;
+ py_out_.AppendText(py_out_oss.str());
+ if (!py.InstallPip(&py_out)) {
+ std::ostringstream py_out_oss;
+ py_out_oss << "Failed to install pip: " << py_out;
+ py_out_.AppendText(py_out_oss.str());
+ }
+ }
+
+ const std::vector<std::string> pip_deps{
+ "pillow",
+ "pydub",
+ "pyaudio",
+ "playsound==1.2.2",
+ "torch --extra-index-url https://download.pytorch.org/whl/cu116",
+ "git+https://github.com/openai/whisper.git",
+ "openvr",
+ "editdistance",
+ "pydub",
+ "python-osc",
+ };
+
+ for (const auto& pip_dep : pip_deps) {
+ {
+ std::ostringstream py_out_oss;
+ py_out_oss << "Installing " << pip_dep << std::endl;
+ py_out_.AppendText(py_out_oss.str());
+ }
+ std::string py_out;
+ bool res = py.InvokeWithArgs({ "-m", "pip", "install", pip_dep }, &py_out);
+ if (!res) {
+ std::ostringstream py_out_oss;
+ py_out_oss << "Failed to install " << pip_dep << ": " << py_out << std::endl;
+ py_out_.AppendText(py_out_oss.str());
+ return;
+ }
+ }
+
+ py_out_.AppendText("Python virtual environment successfully set up!\n");
+}
+
+void Frame::LoadAndSetIcon(const std::string& icon_path) {
+ if (!std::filesystem::exists(icon_path)) {
+ wxLogFatalError("Logo is missing from %s", icon_path.c_str());
+ }
+ wxBitmap icon_img(icon_path, wxBITMAP_TYPE_PNG);
+ wxIcon icon;
+ icon.CopyFromBitmap(icon_img);
+ SetIcon(icon);
+}
+
diff --git a/GUI/GUI/GUI/Frame.h b/GUI/GUI/GUI/Frame.h
index 4dcfd4a..62e9169 100644
--- a/GUI/GUI/GUI/Frame.h
+++ b/GUI/GUI/GUI/Frame.h
@@ -13,8 +13,15 @@ public:
private:
wxPNGHandler png_handler_;
+ wxPanel py_panel_;
+ wxBoxSizer py_panel_sizer_;
+ wxButton py_version_button_;
+ wxButton py_setup_button_;
+ wxTextCtrl py_out_;
- void OnHello(wxCommandEvent& event);
void OnExit(wxCommandEvent& event);
- void OnAbout(wxCommandEvent& event);
+ void OnGetPythonVersion(wxCommandEvent& event);
+ void OnSetupPython(wxCommandEvent& event);
+
+ void LoadAndSetIcon(const std::string& icon_path);
};
diff --git a/GUI/GUI/GUI/GUI.vcxproj b/GUI/GUI/GUI/GUI.vcxproj
index 79bb220..223f47e 100644
--- a/GUI/GUI/GUI/GUI.vcxproj
+++ b/GUI/GUI/GUI/GUI.vcxproj
@@ -138,10 +138,12 @@
<ClCompile Include="App.cpp" />
<ClCompile Include="Frame.cpp" />
<ClCompile Include="main.cpp" />
+ <ClCompile Include="PythonWrapper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="App.h" />
<ClInclude Include="Frame.h" />
+ <ClInclude Include="PythonWrapper.h" />
<ClInclude Include="ScopeGuard.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/GUI/GUI/GUI/GUI.vcxproj.filters b/GUI/GUI/GUI/GUI.vcxproj.filters
index c332693..74e4659 100644
--- a/GUI/GUI/GUI/GUI.vcxproj.filters
+++ b/GUI/GUI/GUI/GUI.vcxproj.filters
@@ -24,16 +24,22 @@
<ClCompile Include="Frame.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="PythonWrapper.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
- <ClInclude Include="ScopeGuard.h">
- <Filter>Source Files</Filter>
+ <ClInclude Include="PythonWrapper.h">
+ <Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="App.h">
- <Filter>Source Files</Filter>
+ <Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Frame.h">
- <Filter>Source Files</Filter>
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ScopeGuard.h">
+ <Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/GUI/GUI/GUI/PythonWrapper.cpp b/GUI/GUI/GUI/PythonWrapper.cpp
new file mode 100644
index 0000000..27d12fd
--- /dev/null
+++ b/GUI/GUI/GUI/PythonWrapper.cpp
@@ -0,0 +1,54 @@
+#include "PythonWrapper.h"
+
+#include <stdio.h>
+
+#include <sstream>
+
+bool PythonWrapper::InvokeWithArgs(std::vector<std::string>&& args, std::string* out) {
+ std::ostringstream cmd_oss;
+ cmd_oss << "Resources/Python/python.exe";
+ for (const auto& arg : args) {
+ cmd_oss << " " << arg;
+ }
+
+ wxArrayString cmd_output_ary;
+ long result = wxExecute(cmd_oss.str(), cmd_output_ary);
+ std::ostringstream cmd_out_oss;
+ for (const auto& line : cmd_output_ary) {
+ if (!cmd_out_oss.str().empty()) {
+ cmd_out_oss << std::endl;
+ }
+ cmd_out_oss << line;
+ }
+ if (result == -1) {
+ std::ostringstream err_oss;
+ err_oss << "Error while executing python command \"" << cmd_oss.str() << "\": Failed to launch process";
+ *out = err_oss.str();
+ return false;
+ } else if (result) {
+ std::ostringstream err_oss;
+ err_oss << "Error while executing python command \"" << cmd_oss.str() << "\": Process returned " << result << ": " << cmd_out_oss.str();
+ *out = err_oss.str();
+ return false;
+ }
+
+ *out = cmd_out_oss.str();
+ return true;
+}
+
+
+std::string PythonWrapper::GetVersion() {
+ std::string result;
+ bool ok = InvokeWithArgs({ "--version" }, &result);
+ if (!ok) {
+ wxLogFatalError("Failed to get python version: %s", result.c_str());
+ }
+ return result;
+}
+
+bool PythonWrapper::InstallPip(std::string* out) {
+ std::string result;
+
+ std::string pip_path = "Resources/Python/get-pip.py";
+ return InvokeWithArgs({ pip_path }, out);
+}
diff --git a/GUI/GUI/GUI/PythonWrapper.h b/GUI/GUI/GUI/PythonWrapper.h
new file mode 100644
index 0000000..607507d
--- /dev/null
+++ b/GUI/GUI/GUI/PythonWrapper.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <wx/wxprec.h>
+
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+#include <string>
+#include <vector>
+
+/*
+ * This class wraps interactions with the embedded Python interpreter.
+*/
+class PythonWrapper
+{
+public:
+ // Invoke the interpreter with arguments.
+ // On error, sets `out` to an error message and returns false.
+ bool InvokeWithArgs(std::vector<std::string>&& args, std::string* out);
+
+ // Execute python --version.
+ std::string GetVersion();
+
+ // Execute get-pip.py.
+ bool InstallPip(std::string* out);
+};
+
diff --git a/GUI/package.ps1 b/GUI/package.ps1
index 4b25f3f..0c2cec0 100644
--- a/GUI/package.ps1
+++ b/GUI/package.ps1
@@ -8,5 +8,6 @@ mkdir $install_dir > $null
mkdir $install_dir/Resources > $null
cp ../Images/logo.png TaSTT/Resources
cp -Recurse ../Python TaSTT/Resources/Python
+cp -Recurse ../Scripts TaSTT/Resources/Scripts
cp GUI/x64/Release/GUI.exe TaSTT/TaSTT.exe
diff --git a/Python/python310._pth b/Python/python310._pth
index 2676d09..91fe233 100644
--- a/Python/python310._pth
+++ b/Python/python310._pth
@@ -4,7 +4,10 @@ python310.zip
# Uncomment to run site.main() automatically
import site
+# TaSTT Python scripts
+../Scripts
+
Lib
Lib/site-packages
-Scripts
Dependencies/future-0.18.2
+
diff --git a/emotes.py b/Scripts/emotes.py
index b922fdf..b922fdf 100644
--- a/emotes.py
+++ b/Scripts/emotes.py
diff --git a/generate_fonts.py b/Scripts/generate_fonts.py
index ef5bfc5..ef5bfc5 100644
--- a/generate_fonts.py
+++ b/Scripts/generate_fonts.py
diff --git a/generate_params.py b/Scripts/generate_params.py
index 323502c..323502c 100644
--- a/generate_params.py
+++ b/Scripts/generate_params.py
diff --git a/generate_utils.py b/Scripts/generate_utils.py
index e8fcc8b..e8fcc8b 100644
--- a/generate_utils.py
+++ b/Scripts/generate_utils.py
diff --git a/libtastt.py b/Scripts/libtastt.py
index bee535f..bee535f 100644
--- a/libtastt.py
+++ b/Scripts/libtastt.py
diff --git a/libunity.py b/Scripts/libunity.py
index f9e9e28..f9e9e28 100644
--- a/libunity.py
+++ b/Scripts/libunity.py
diff --git a/obfuscate.py b/Scripts/obfuscate.py
index 8d01e10..8d01e10 100644
--- a/obfuscate.py
+++ b/Scripts/obfuscate.py
diff --git a/osc_ctrl.py b/Scripts/osc_ctrl.py
index 34d1a36..34d1a36 100644
--- a/osc_ctrl.py
+++ b/Scripts/osc_ctrl.py
diff --git a/steamvr.py b/Scripts/steamvr.py
index ed4150c..ed4150c 100644
--- a/steamvr.py
+++ b/Scripts/steamvr.py
diff --git a/string_matcher.py b/Scripts/string_matcher.py
index 461f180..461f180 100644
--- a/string_matcher.py
+++ b/Scripts/string_matcher.py
diff --git a/transcribe.py b/Scripts/transcribe.py
index 62e6add..62e6add 100644
--- a/transcribe.py
+++ b/Scripts/transcribe.py