Skip to content

Commit

Permalink
Robustness fixes. Adding polyglot assist button (#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
royshil committed Mar 18, 2024
1 parent bccbc36 commit 1f01096
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 24 deletions.
12 changes: 9 additions & 3 deletions src/obs-source-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

inline bool is_obs_source_text(obs_source_t *source)
{
if (source == nullptr) {
return false;
}
const auto source_id = obs_source_get_id(source);
return strcmp(source_id, "text_ft2_source_v2") == 0 ||
strcmp(source_id, "text_gdiplus_v2") == 0;
Expand All @@ -16,9 +19,12 @@ inline bool is_obs_source_text(obs_source_t *source)
inline bool is_obs_source_text(const std::string &source_name)
{
obs_source_t *source = obs_get_source_by_name(source_name.c_str());
const bool is_text = is_obs_source_text(source);
obs_source_release(source);
return is_text;
if (source != nullptr) {
const bool is_text = is_obs_source_text(source);
obs_source_release(source);
return is_text;
}
return false;
}

struct source_render_data {
Expand Down
19 changes: 19 additions & 0 deletions src/request-data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ std::size_t writeFunctionUint8Vector(void *ptr, std::size_t size, size_t nmemb,
return size * nmemb;
}

bool hasOnlyValidURLCharacters(const std::string &url)
{
// This pattern allows typical URL characters including percent encoding
const std::regex pattern(R"(^[A-Za-z0-9\-._~:/?#\[\]@!$&'()*+,;=%]+$)");
return std::regex_match(url, pattern);
}

size_t header_callback(char *buffer, size_t size, size_t nitems, void *userdata)
{
std::map<std::string, std::string> *headers =
Expand Down Expand Up @@ -193,6 +200,15 @@ struct request_data_handler_response request_data_handler(url_source_request_dat
response.status_code = URL_SOURCE_REQUEST_STANDARD_ERROR_CODE;
return response;
}
// validate the url
if (!hasOnlyValidURLCharacters(request_data->url)) {
obs_log(LOG_INFO, "URL is invalid");
// Return an error response
response.error_message = "URL is invalid";
response.status_code = URL_SOURCE_REQUEST_STANDARD_ERROR_CODE;
return response;
}

// Build the request with libcurl
CURL *curl = curl_easy_init();
if (!curl) {
Expand Down Expand Up @@ -279,6 +295,7 @@ struct request_data_handler_response request_data_handler(url_source_request_dat
json["input"] = textStr;
}
if (response.status_code == URL_SOURCE_REQUEST_BENIGN_ERROR_CODE) {
curl_easy_cleanup(curl);
return response;
}
} else {
Expand All @@ -292,6 +309,7 @@ struct request_data_handler_response request_data_handler(url_source_request_dat
response.error_message = "Failed to get source by name";
response.status_code =
URL_SOURCE_REQUEST_STANDARD_ERROR_CODE;
curl_easy_cleanup(curl);
return response;
}

Expand Down Expand Up @@ -320,6 +338,7 @@ struct request_data_handler_response request_data_handler(url_source_request_dat
"Failed to get RGBA from source render";
response.status_code =
URL_SOURCE_REQUEST_STANDARD_ERROR_CODE;
curl_easy_cleanup(curl);
return response;
}
destroy_source_render_data(&tf);
Expand Down
90 changes: 69 additions & 21 deletions src/ui/RequestBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,32 @@ bool add_sources_to_qcombobox(void *list, obs_source_t *source)
return true;
}

void set_widgets_enabled_in_layout(QLayout *layout, bool enabled,
std::vector<QWidget *> exclude = {})
{
if (!layout)
return;

for (int i = 0; i < layout->count(); ++i) {
QLayoutItem *item = layout->itemAt(i);
QWidget *widget = item->widget();
// check if widget is excluded
bool excluded = false;
for (const QWidget *excludeWidget : exclude) {
if (widget == excludeWidget) {
excluded = true;
}
}
if (widget && !excluded) {
widget->setEnabled(enabled);
}
if (item->layout()) {
// Recursively enable/disable widgets in nested layouts, excluding the specified widget
set_widgets_enabled_in_layout(item->layout(), enabled, exclude);
}
}
}

RequestBuilder::RequestBuilder(url_source_request_data *request_data,
std::function<void()> update_handler, QWidget *parent)
: QDialog(parent), ui(new Ui::RequestBuilder)
Expand Down Expand Up @@ -90,15 +116,31 @@ RequestBuilder::RequestBuilder(url_source_request_data *request_data,
ui->urlRequestOptionsGroup->setVisible(request_data->url_or_file == "url");

auto toggleFileUrlButtons = [=]() {
ui->urlOrFileButton->setEnabled(ui->fileRadioButton->isChecked());
// hide the urlRequestOptionsGroup if file is selected
ui->urlRequestOptionsGroup->setVisible(ui->urlRadioButton->isChecked());
// adjust the size of the dialog to fit the content
if (ui->fileRadioButton->isChecked()) {
ui->urlOrFileButton->setEnabled(true);
ui->urlRequestOptionsGroup->setVisible(false);
} else if (ui->urlRadioButton->isChecked()) {
ui->urlOrFileButton->setEnabled(false);
ui->urlRequestOptionsGroup->setVisible(true);
}
this->adjustSize();
};
// show file selector button if file is selected
connect(ui->fileRadioButton, &QRadioButton::toggled, this, toggleFileUrlButtons);
connect(ui->urlRadioButton, &QRadioButton::toggled, this, toggleFileUrlButtons);
connect(ui->toolButton_polyglot, &QToolButton::clicked, this, [=]() {
ui->urlRadioButton->setChecked(true);
toggleFileUrlButtons();
ui->methodComboBox->setCurrentIndex(1);
ui->urlLineEdit->setText("http:https://localhost:18080/translate");
ui->bodyTextEdit->setText(
"{\"text\":\"{{input}}\", \"source_lang\":\"eng_Latn\", \"target_lang\":\"spa_Latn\"}");
ui->obsTextSourceEnabledCheckBox->setChecked(true);
ui->obsTextSourceSkipSameCheckBox->setChecked(true);
ui->sslOptionsCheckbox->setChecked(false);
ui->outputTypeComboBox->setCurrentIndex(0);
ui->outputRegexLineEdit->setText("");
});

ui->methodComboBox->setCurrentText(QString::fromStdString(request_data->method));
ui->checkBox_failonhttperrorcodes->setChecked(request_data->fail_on_http_error);
Expand Down Expand Up @@ -395,6 +437,8 @@ RequestBuilder::RequestBuilder(url_source_request_data *request_data,

connect(this, &RequestBuilder::show_response_dialog_signal, this,
&RequestBuilder::show_response_dialog);
connect(this, &RequestBuilder::show_error_message_signal, this,
&RequestBuilder::show_error_message);

connect(ui->sendButton, &QPushButton::clicked, this, [=]() {
// Hide the error message label
Expand All @@ -404,8 +448,8 @@ RequestBuilder::RequestBuilder(url_source_request_data *request_data,
ui->sendButton->setEnabled(false);
ui->sendButton->setText("Sending...");

// Create a request_data_handler function that will be called by the thread
auto request_data_handler_ex = [this, saveSettingsToRequestData]() {
// Create a thread to send the request to prevent the UI from hanging
std::thread request_data_handler_thread([this, saveSettingsToRequestData]() {
// Get an interim request_data struct with the current settings
url_source_request_data request_data_test;
saveSettingsToRequestData(&request_data_test);
Expand All @@ -416,22 +460,12 @@ RequestBuilder::RequestBuilder(url_source_request_data *request_data,
request_data_handler(&request_data_test);

if (response.status_code != URL_SOURCE_REQUEST_SUCCESS) {
// Show the error message label
this->ui->errorMessageLabel->setText(
QString::fromStdString(response.error_message));
this->ui->errorMessageLabel->setVisible(true);
// enable the send button
this->ui->sendButton->setEnabled(true);
this->ui->sendButton->setText("Test Request");
return;
emit show_error_message_signal(response.error_message);
} else {
// Show the response dialog
emit show_response_dialog_signal(response);
}

// Show the response dialog
emit show_response_dialog_signal(response);
};

// Create a thread to send the request to prevent the UI from hanging
std::thread request_data_handler_thread(request_data_handler_ex);
});
request_data_handler_thread.detach();
});

Expand All @@ -452,6 +486,20 @@ RequestBuilder::RequestBuilder(url_source_request_data *request_data,
adjustSize();
}

void RequestBuilder::show_error_message(const std::string &error_message)
{
if (!error_message.empty()) {
// Show the error message label
this->ui->errorMessageLabel->setText(QString::fromStdString(error_message));
this->ui->errorMessageLabel->setVisible(true);
} else {
this->ui->errorMessageLabel->setVisible(false);
}
// enable the send button
this->ui->sendButton->setEnabled(true);
this->ui->sendButton->setText("Test Request");
}

void RequestBuilder::show_response_dialog(const request_data_handler_response &response)
{
obs_log(LOG_INFO, "Response HTTP status code: %ld", response.http_status_code);
Expand Down
2 changes: 2 additions & 0 deletions src/ui/RequestBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ class RequestBuilder : public QDialog {

private slots:
void show_response_dialog(const request_data_handler_response &response);
void show_error_message(const std::string &error_message);

signals:
void show_response_dialog_signal(const request_data_handler_response &response);
void show_error_message_signal(const std::string &error_message);

private:
Ui::RequestBuilder *ui;
Expand Down
20 changes: 20 additions & 0 deletions src/ui/requestbuilder.ui
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,26 @@
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="toolButton_polyglot">
<property name="text">
<string>PolyGlot</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down

0 comments on commit 1f01096

Please sign in to comment.