Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add timeout settings for YouTube requests #28

Merged
merged 4 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,14 @@ def _handle_finished(self, reply: QNetworkReply):


class AbstractYoutubeEngine:
def __init__(self, model: ResultTableModel, request_limit: int):
def __init__(self, model: ResultTableModel, request_limit: int, request_timeout_sec: int = 10):
self.error = ""
self._model = model
self._request_limit = request_limit
self._request_timeout_sec = request_timeout_sec

def set_request_timeout_sec(self, value_sec: int):
self._request_timeout_sec = value_sec

def search(self, request_text: str):
pass
Expand Down Expand Up @@ -207,10 +211,10 @@ def published_time_sort_cast(published_time: str):
return float(pb_timedelta.replace(":", ""))

def _create_video_searcher(self, request_text: str):
return VideosSearch(request_text, limit=self._request_limit)
return VideosSearch(request_text, limit=self._request_limit, timeout=self._request_timeout_sec)

def _get_video_info(self, video_id: str):
return Video.getInfo(video_id)
return Video.getInfo(video_id, timeout=self._request_timeout_sec)

def _get_channel_info(self, channel_id: str):
return Channel.get(channel_id)
Expand Down
105 changes: 90 additions & 15 deletions settings.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
from dataclasses import dataclass
from PySide6.QtCore import (
Signal,
QByteArray,
QSettings
)
from PySide6.QtWidgets import (
QWidget,
QLineEdit,
QVBoxLayout,
QDialog,
QDialogButtonBox,
QLabel,
QComboBox,
QMessageBox,
QCheckBox
QCheckBox,
QTabWidget,
QSpinBox
)


@dataclass
class SettingsKey:
key: str
default_value: any


class Settings:
MainWindowGeometry = SettingsKey("main_window_geometry", QByteArray())
RequestLimit = SettingsKey("request_limit", 10)
Expand All @@ -32,6 +38,7 @@ class Settings:
LastActiveDetailsTab = SettingsKey("last_active_details_tab", 0)
AnalyticsFollowTableSelect = SettingsKey("analytics_follow_table_select", True)
LastActiveChartIndex = SettingsKey("last_active_chart_index", 0)
RequestTimeoutSec = SettingsKey("request_timeout_sec", 10)

def __init__(self, app_name: str):
self._impl = QSettings(QSettings.Format.IniFormat, QSettings.Scope.UserScope, app_name)
Expand All @@ -45,12 +52,12 @@ def set(self, key: SettingsKey, value: any):
self._impl.setValue(key.key, value)


class SettingsDialog(QDialog):
def __init__(self, settings: Settings, parent = None):
class GeneralTab(QWidget):
language_changed = Signal()

def __init__(self, settings: Settings, parent=None):
super().__init__(parent)
self._settings = settings
self._need_restart = False
self.setWindowTitle(self.tr("Settings"))
layout = QVBoxLayout()

yt_api_key_label = QLabel(self.tr("YouTube API Key:"))
Expand Down Expand Up @@ -81,12 +88,84 @@ def __init__(self, settings: Settings, parent = None):
self._theme_combo.setCurrentIndex(int(self._settings.get(Settings.Theme)))
layout.addWidget(self._theme_combo)

analytics_label = QLabel(self.tr("Analytics:"))
layout.addWidget(analytics_label)
self.setLayout(layout)

def save_settings(self):
self._settings.set(Settings.YouTubeApiKey, self._yt_api_key_edit.text())
if self._language_combo.currentText() == "Русский":
self._settings.set(Settings.Language, "Ru")
else:
self._settings.set(Settings.Language, "En")
self._settings.set(Settings.Theme, self._theme_combo.currentIndex())

def get_current_language(self):
return self._language_combo.currentText()

def _on_language_changed(self):
self.language_changed.emit()


class AnalyticsTab(QWidget):
def __init__(self, settings: Settings, parent=None):
super().__init__(parent)
self._settings = settings
layout = QVBoxLayout()

self._follow_for_analytics_checkbox = QCheckBox(self.tr("Follow table selections in analytics charts"))
self._follow_for_analytics_checkbox.setToolTip(self.tr("Highlight the selected item on the analytics charts"))
self._follow_for_analytics_checkbox.setChecked(self._settings.get(Settings.AnalyticsFollowTableSelect))
layout.addWidget(self._follow_for_analytics_checkbox)
layout.addStretch()

self.setLayout(layout)

def save_settings(self):
self._settings.set(Settings.AnalyticsFollowTableSelect, self._follow_for_analytics_checkbox.isChecked())


class AdvancedTab(QWidget):
def __init__(self, settings: Settings, parent=None):
super().__init__(parent)
self._settings = settings
layout = QVBoxLayout()

timeout_label = QLabel(self.tr("Request timeout in seconds:"))
layout.addWidget(timeout_label)
self._request_timeout_sec_edit = QSpinBox()
self._request_timeout_sec_edit.setMinimum(2)
self._request_timeout_sec_edit.setMaximum(1000)
self._request_timeout_sec_edit.setToolTip(self.tr("Set the maximum waiting time in seconds for YouTube request"))
self._request_timeout_sec_edit.setValue(int(self._settings.get(Settings.RequestTimeoutSec)))
layout.addWidget(self._request_timeout_sec_edit)
layout.addStretch()

self.setLayout(layout)

def save_settings(self):
self._settings.set(Settings.RequestTimeoutSec, self._request_timeout_sec_edit.value())


class SettingsDialog(QDialog):
def __init__(self, settings: Settings, parent=None):
super().__init__(parent)
self._settings = settings
self._need_restart = False
self.setWindowTitle(self.tr("Settings"))

layout = QVBoxLayout()
tab_widget = QTabWidget()

self._general_tab = GeneralTab(settings)
self._general_tab.language_changed.connect(self._on_force_restart)
tab_widget.addTab(self._general_tab, self.tr("General"))

self._analytics_tab = AnalyticsTab(settings)
tab_widget.addTab(self._analytics_tab, self.tr("Analytics"))

self._advanced_tab = AdvancedTab(settings)
tab_widget.addTab(self._advanced_tab, self.tr("Advanced"))

layout.addWidget(tab_widget)

button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
button_box.accepted.connect(self._on_accepted)
Expand All @@ -99,24 +178,20 @@ def is_need_restart(self):
return self._need_restart

def _on_accepted(self):
self._settings.set(Settings.YouTubeApiKey, self._yt_api_key_edit.text())
if self._language_combo.currentText() == "Русский":
self._settings.set(Settings.Language, "Ru")
else:
self._settings.set(Settings.Language, "En")
self._settings.set(Settings.Theme, self._theme_combo.currentIndex())
self._general_tab.save_settings()
self._analytics_tab.save_settings()
self._advanced_tab.save_settings()

if self._need_restart:
text = self.tr("Restart the application now to apply the selected language?")
if QMessageBox.question(self, self.windowTitle(), text) == QMessageBox.StandardButton.No:
self._need_restart = False

self._settings.set(Settings.AnalyticsFollowTableSelect, self._follow_for_analytics_checkbox.isChecked())
self.accept()

def _on_rejected(self):
self._need_restart = False
self.reject()

def _on_language_changed(self):
def _on_force_restart(self):
self._need_restart = True
131 changes: 80 additions & 51 deletions translations/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,32 @@
<translation>All rights reserved</translation>
</message>
</context>
<context>
<name>AdvancedTab</name>
<message>
<location filename="../settings.py" line="132"/>
<source>Request timeout in seconds:</source>
<translation>Request timeout in seconds:</translation>
</message>
<message>
<location filename="../settings.py" line="137"/>
<source>Set the maximum waiting time in seconds for YouTube request</source>
<translation>Set the maximum waiting time in seconds for YouTube request</translation>
</message>
</context>
<context>
<name>AnalyticsTab</name>
<message>
<location filename="../settings.py" line="114"/>
<source>Follow table selections in analytics charts</source>
<translation>Follow table selections in analytics charts</translation>
</message>
<message>
<location filename="../settings.py" line="115"/>
<source>Highlight the selected item on the analytics charts</source>
<translation>Highlight the selected item on the analytics charts</translation>
</message>
</context>
<context>
<name>AnalyticsWidget</name>
<message>
Expand Down Expand Up @@ -77,6 +103,49 @@
<translation>Don&apos;t ask again</translation>
</message>
</context>
<context>
<name>GeneralTab</name>
<message>
<location filename="../settings.py" line="63"/>
<source>YouTube API Key:</source>
<translation>YouTube API Key:</translation>
</message>
<message>
<location filename="../settings.py" line="66"/>
<source>Set the key to use the YouTube API for YouTube search</source>
<translation>Set the key to use the YouTube API for YouTube search</translation>
</message>
<message>
<location filename="../settings.py" line="69"/>
<source>Language:</source>
<translation>Language:</translation>
</message>
<message>
<location filename="../settings.py" line="72"/>
<source>Set the interface language</source>
<translation>Set the interface language</translation>
</message>
<message>
<location filename="../settings.py" line="82"/>
<source>Theme:</source>
<translation>Theme:</translation>
</message>
<message>
<location filename="../settings.py" line="85"/>
<source>Set the interface color theme</source>
<translation>Set the interface color theme</translation>
</message>
<message>
<location filename="../settings.py" line="86"/>
<source>System</source>
<translation>System</translation>
</message>
<message>
<location filename="../settings.py" line="87"/>
<source>Dark</source>
<translation>Dark</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
Expand Down Expand Up @@ -278,67 +347,27 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settings.py" line="53"/>
<location filename="../settings.py" line="153"/>
<source>Settings</source>
<translation>Settings</translation>
</message>
<message>
<location filename="../settings.py" line="56"/>
<source>YouTube API Key:</source>
<translation>YouTube API Key:</translation>
</message>
<message>
<location filename="../settings.py" line="59"/>
<source>Set the key to use the YouTube API for YouTube search</source>
<translation>Set the key to use the YouTube API for YouTube search</translation>
</message>
<message>
<location filename="../settings.py" line="62"/>
<source>Language:</source>
<translation>Language:</translation>
</message>
<message>
<location filename="../settings.py" line="65"/>
<source>Set the interface language</source>
<translation>Set the interface language</translation>
</message>
<message>
<location filename="../settings.py" line="75"/>
<source>Theme:</source>
<translation>Theme:</translation>
</message>
<message>
<location filename="../settings.py" line="78"/>
<source>Set the interface color theme</source>
<translation>Set the interface color theme</translation>
</message>
<message>
<location filename="../settings.py" line="79"/>
<source>System</source>
<translation>System</translation>
<location filename="../settings.py" line="160"/>
<source>General</source>
<translation>General</translation>
</message>
<message>
<location filename="../settings.py" line="80"/>
<source>Dark</source>
<translation>Dark</translation>
</message>
<message>
<location filename="../settings.py" line="84"/>
<source>Analytics:</source>
<translation>Analytics:</translation>
</message>
<message>
<location filename="../settings.py" line="86"/>
<source>Follow table selections in analytics charts</source>
<translation>Follow table selections in analytics charts</translation>
<location filename="../settings.py" line="163"/>
<source>Analytics</source>
<translation>Analytics</translation>
</message>
<message>
<location filename="../settings.py" line="87"/>
<source>Highlight the selected item on the analytics charts</source>
<translation>Highlight the selected item on the analytics charts</translation>
<location filename="../settings.py" line="166"/>
<source>Advanced</source>
<translation>Advanced</translation>
</message>
<message>
<location filename="../settings.py" line="111"/>
<location filename="../settings.py" line="187"/>
<source>Restart the application now to apply the selected language?</source>
<translation>Restart the application now to apply the selected language?</translation>
</message>
Expand Down
Loading
Loading