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 YouTube trends tab #38

Merged
merged 13 commits into from
Jan 2, 2025
11 changes: 6 additions & 5 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ jobs:

steps:
- uses: actions/checkout@v4
- name: Set up Python 3.10
- name: Set up Python 3.12
uses: actions/setup-python@v3
with:
python-version: "3.10"
python-version: "3.12"
- name: Install dependencies
run: |
sudo apt install -y freeglut3 freeglut3-dev
sudo apt install -y libegl1
python -m pip install --upgrade pip
pip install flake8
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
Expand All @@ -37,5 +37,6 @@ jobs:
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with unittest
run: |
python test_engines.py
python test_export.py
python -m unittest tests.test_engines
python -m unittest tests.test_export
python -m unittest tests.test_settings
8 changes: 3 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
build
dist
*build
*dist
.vscode
.venv
youtube-analyzer.spec
*.spec
__pycache__
translations/*.qm
youtube-analyzer.build
youtube-analyzer.dist
Output
.coverage*
unit_test_*
3 changes: 1 addition & 2 deletions compile_executable.bat
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
.venv\Scripts\pyinstaller.exe --windowed --icon=logo.png youtube-analyzer.py
.venv\Scripts\pyinstaller.exe --windowed --icon=logo.png --name youtube-analyzer youtubeanalyzer/__main__.py
copy logo.png dist\youtube-analyzer\logo.png

call compile_translations.bat
mkdir dist\youtube-analyzer\translations
copy translations\en.qm dist\youtube-analyzer\translations\en.qm
copy translations\ru.qm dist\youtube-analyzer\translations\ru.qm
9 changes: 4 additions & 5 deletions compile_executable_nuitka.bat
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
.venv\Scripts\python.exe -m nuitka --standalone --disable-console --include-package-data=googleapiclient --enable-plugin=pyside6 --windows-icon-from-ico=logo.png youtube-analyzer.py
.venv\Scripts\python.exe -m nuitka --standalone --windows-console-mode=disable --include-package-data=googleapiclient --enable-plugin=pyside6 --include-module=PySide6.support.deprecated --windows-icon-from-ico=logo.png --output-filename=youtube-analyzer youtubeanalyzer/__main__.py

copy logo.png youtube-analyzer.dist\logo.png
copy logo.png __main__.dist\logo.png

call compile_translations.bat
mkdir youtube-analyzer.dist\translations
copy translations\en.qm youtube-analyzer.dist\translations\en.qm
copy translations\ru.qm youtube-analyzer.dist\translations\ru.qm
mkdir __main__.dist\translations
copy translations\ru.qm __main__.dist\translations\ru.qm
1 change: 0 additions & 1 deletion compile_translations.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
".venv/Scripts/pyside6-lrelease.exe" translations/en.ts -qm translations/en.qm
".venv/Scripts/pyside6-lrelease.exe" translations/ru.ts -qm translations/ru.qm
Binary file modified requirements.txt
Binary file not shown.
Empty file added tests/__init__.py
Empty file.
14 changes: 14 additions & 0 deletions tests/data/settings_version_1.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[General]
request_limit=30
dont_ask_again_exit=0
main_window_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\xff\xff\xff\xf8\0\0\a\x7f\0\0\x4\a\0\0\x1 \0\0\0\x8a\0\0\x6_\0\0\x3}\0\0\0\0\x2\0\0\0\a\x80\0\0\0\0\0\0\0\x17\0\0\a\x7f\0\0\x4\a)
main_splitter_state=1279, 619
details=true
youtube_api_key=Abcd1234
language=Ru
theme=0
analytics_follow_table_select=true
request_timeout_sec=10
last_active_chart_index=2
main_table_header_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\x2\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5\xca\0\0\0\a\x1\x1\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x84\0\0\0\0\0\0\0\a\0\0\x1\xfb\0\0\0\x1\0\0\0\0\0\0\0\x8b\0\0\0\x1\0\0\0\0\0\0\0\x92\0\0\0\x1\0\0\0\0\0\0\0\xa7\0\0\0\x1\0\0\0\0\0\0\0\xaf\0\0\0\x1\0\0\0\0\0\0\0\xb0\0\0\0\x1\0\0\0\0\0\0\0\xac\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\0\0\0\0\0\0\0\0)
last_active_details_tab=1
6 changes: 3 additions & 3 deletions test_engines.py → tests/test_engines.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import unittest
from datetime import timedelta
from model import (ResultFields, ResultTableModel)
from engine import (
from youtubeanalyzer.model import (ResultFields, ResultTableModel)
from youtubeanalyzer.engine import (
timedelta_to_str, view_count_to_int, subcriber_count_to_int,
YoutubeGrepEngine, YoutubeApiEngine)

Expand Down Expand Up @@ -122,7 +122,7 @@ def _get_channel_info(self, _channel_id: str):

class MockApiEngine(YoutubeApiEngine):
def __init__(self, empty=False, exception=False):
super().__init__(ResultTableModel(None), 1, "")
super().__init__("", ResultTableModel(None), 1)
self._exception = exception
self._search_responce = {
"items": []
Expand Down
4 changes: 2 additions & 2 deletions test_export.py → tests/test_export.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import os
import unittest
from datetime import timedelta
from model import (
from youtubeanalyzer.model import (
ResultTableModel,
make_result_row
)
from export import (
from youtubeanalyzer.export import (
export_to_xlsx,
export_to_csv,
export_to_html
Expand Down
59 changes: 59 additions & 0 deletions tests/test_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import os
import shutil
import unittest
from youtubeanalyzer.settings import (
Settings,
CurrentSettingsVersion
)


class TestSettingsModule(unittest.TestCase):

def test_settings_keys_persistance(self):
self.assertEqual(Settings.MainWindowGeometry.key, "main_window_geometry")
self.assertEqual(Settings.RequestLimit.key, "request_limit")
self.assertEqual(Settings.LastSaveDir.key, "last_save_dir")
self.assertEqual(Settings.DontAskAgainExit.key, "dont_ask_again_exit")
self.assertEqual(Settings.YouTubeApiKey.key, "youtube_api_key")
self.assertEqual(Settings.Language.key, "language")
self.assertEqual(Settings.Theme.key, "theme")
self.assertEqual(Settings.MainSplitterState.key, "main_splitter_state")
self.assertEqual(Settings.DetailsVisible.key, "details")
self.assertEqual(Settings.LastActiveDetailsTab.key, "last_active_details_tab")
self.assertEqual(Settings.AnalyticsFollowTableSelect.key, "analytics_follow_table_select")
self.assertEqual(Settings.LastActiveChartIndex.key, "last_active_chart_index")
self.assertEqual(Settings.RequestTimeoutSec.key, "request_timeout_sec")
self.assertEqual(Settings.MainTableHeaderState.key, "main_table_header_state")
self.assertEqual(Settings.MainTabsArray.key, "main_tabs")
self.assertEqual(Settings.TabWorkspaceIndex.key, "tab_workspace_index")
self.assertEqual(Settings.ActiveTabIndex.key, "active_tab_index")

def test_upgrade_from_version_1(self):
etalon_test_file = "tests/data/settings_version_1.ini"
target_test_file = "settings.ini"
shutil.copyfile(etalon_test_file, target_test_file)
settings = Settings("test", target_test_file)
# Check removed keys
self.assertEqual(int(settings.get(Settings.RequestLimit)), 10)
self.assertEqual(int(settings.get(Settings.LastActiveChartIndex)), 0)
self.assertEqual(int(settings.get(Settings.LastActiveDetailsTab)), 0)
self.assertTrue(settings.get(Settings.MainTableHeaderState).isEmpty())
# Check main tab converting
settings.begin_read_array(Settings.MainTabsArray)
settings.set_array_index(0)
self.assertEqual(int(settings.get(Settings.RequestLimit)), 30)
self.assertEqual(int(settings.get(Settings.LastActiveChartIndex)), 2)
self.assertEqual(int(settings.get(Settings.LastActiveDetailsTab)), 1)
self.assertFalse(settings.get(Settings.MainTableHeaderState).isEmpty())
settings.end_array()
self.assertEqual(int(settings.get(Settings.ActiveTabIndex)), 0)
# Check version
self.assertEqual(int(settings.get(Settings.Version)), CurrentSettingsVersion)

@classmethod
def tearDownClass(cls):
os.remove("settings.ini")


if __name__ == "__main__":
unittest.main()
Loading
Loading