qcanvas 1.2.2__tar.gz → 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of qcanvas might be problematic. Click here for more details.

Files changed (149) hide show
  1. {qcanvas-1.2.2 → qcanvas-2.0.0}/PKG-INFO +12 -10
  2. {qcanvas-1.2.2 → qcanvas-2.0.0}/README.md +6 -3
  3. qcanvas-2.0.0/pyproject.toml +57 -0
  4. qcanvas-1.2.2/qcanvas/run.py → qcanvas-2.0.0/qcanvas/__init__.py +19 -19
  5. qcanvas-2.0.0/qcanvas/app.py +93 -0
  6. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/backend_connectors/frontend_resource_manager.py +13 -5
  7. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/backend_connectors/qcanvas_task_master.py +2 -2
  8. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/icons/__init__.py +5 -5
  9. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/icons/_icon_type.py +1 -1
  10. qcanvas-2.0.0/qcanvas/icons/icons.qrc +50 -0
  11. qcanvas-2.0.0/qcanvas/icons/rc_icons.py +2519 -0
  12. qcanvas-2.0.0/qcanvas/settings/__init__.py +6 -0
  13. {qcanvas-1.2.2/qcanvas/util → qcanvas-2.0.0/qcanvas}/settings/_client_settings.py +4 -4
  14. qcanvas-2.0.0/qcanvas/settings/_course_settings.py +54 -0
  15. {qcanvas-1.2.2/qcanvas/util → qcanvas-2.0.0/qcanvas}/settings/_mapped_setting.py +2 -5
  16. {qcanvas-1.2.2/qcanvas/util → qcanvas-2.0.0/qcanvas}/settings/_ui_settings.py +4 -4
  17. qcanvas-2.0.0/qcanvas/theme.py +101 -0
  18. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/content_tree.py +9 -12
  19. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/course_tree/_course_icon_generator.py +3 -3
  20. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/course_tree/course_tree.py +9 -8
  21. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/course_viewer.py +35 -43
  22. qcanvas-2.0.0/qcanvas/ui/course_viewer/tabs/assignment_tab/assignment_tab.py +146 -0
  23. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/assignment_tab/assignment_tree.py +4 -4
  24. qcanvas-2.0.0/qcanvas/ui/course_viewer/tabs/constants.py +1 -0
  25. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/content_tab.py +33 -39
  26. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/file_tab/file_tab.py +4 -4
  27. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/file_tab/file_tree.py +7 -10
  28. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/file_tab/pages_file_tree.py +6 -7
  29. qcanvas-2.0.0/qcanvas/ui/course_viewer/tabs/mail_tab/mail_tab.py +82 -0
  30. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/mail_tab/mail_tree.py +7 -8
  31. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/page_tab/page_tab.py +3 -3
  32. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/page_tab/page_tree.py +5 -5
  33. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/resource_rich_browser.py +15 -21
  34. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tree_widget_data_item.py +1 -1
  35. qcanvas-2.0.0/qcanvas/ui/memory_tree/_tree_memory.py +70 -0
  36. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/memory_tree/memory_tree_widget.py +22 -18
  37. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/memory_tree/memory_tree_widget_item.py +3 -3
  38. qcanvas-2.0.0/qcanvas/ui/qcanvas_window/__init__.py +1 -0
  39. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.0/qcanvas/ui/qcanvas_window}/course_viewer_container.py +10 -10
  40. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.0/qcanvas/ui/qcanvas_window}/options/auto_download_resources_option.py +5 -5
  41. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.0/qcanvas/ui/qcanvas_window}/options/quick_sync_option.py +7 -6
  42. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.0/qcanvas/ui/qcanvas_window}/options/sync_on_start_option.py +7 -6
  43. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.0/qcanvas/ui/qcanvas_window}/options/theme_selection_menu.py +10 -10
  44. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.0/qcanvas/ui/qcanvas_window}/qcanvas_window.py +38 -33
  45. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.0/qcanvas/ui/qcanvas_window}/status_bar_progress_display.py +5 -6
  46. qcanvas-2.0.0/qcanvas/ui/qml_components/AttachmentsList.ui.qml +15 -0
  47. qcanvas-2.0.0/qcanvas/ui/qml_components/AttachmentsListDelegate.qml +77 -0
  48. qcanvas-2.0.0/qcanvas/ui/qml_components/AttachmentsListModel.qml +19 -0
  49. qcanvas-2.0.0/qcanvas/ui/qml_components/AttachmentsPane.qml +12 -0
  50. qcanvas-2.0.0/qcanvas/ui/qml_components/CommentsList.ui.qml +15 -0
  51. qcanvas-2.0.0/qcanvas/ui/qml_components/CommentsListDelegate.ui.qml +118 -0
  52. qcanvas-2.0.0/qcanvas/ui/qml_components/CommentsListModel.qml +56 -0
  53. qcanvas-2.0.0/qcanvas/ui/qml_components/CommentsPane.qml +12 -0
  54. qcanvas-2.0.0/qcanvas/ui/qml_components/DarkTheme.qml +12 -0
  55. qcanvas-2.0.0/qcanvas/ui/qml_components/DecoratedText.ui.qml +44 -0
  56. qcanvas-2.0.0/qcanvas/ui/qml_components/LightTheme.qml +11 -0
  57. qcanvas-2.0.0/qcanvas/ui/qml_components/Spacer.ui.qml +7 -0
  58. qcanvas-2.0.0/qcanvas/ui/qml_components/ThemedRectangle.qml +37 -0
  59. qcanvas-2.0.0/qcanvas/ui/qml_components/__init__.py +3 -0
  60. qcanvas-2.0.0/qcanvas/ui/qml_components/attachments_pane.py +72 -0
  61. qcanvas-2.0.0/qcanvas/ui/qml_components/comments_pane.py +85 -0
  62. qcanvas-2.0.0/qcanvas/ui/qml_components/qml_bridge_types.py +95 -0
  63. qcanvas-2.0.0/qcanvas/ui/qml_components/qml_pane.py +22 -0
  64. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/setup/setup_checker.py +1 -1
  65. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/setup/setup_dialog.py +27 -10
  66. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/util/auto_downloader.py +9 -7
  67. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/util/basic_fonts.py +2 -2
  68. qcanvas-2.0.0/qcanvas/util/context_dict.py +12 -0
  69. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/util/file_icons.py +11 -19
  70. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/util/layouts.py +5 -7
  71. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/util/paths.py +17 -6
  72. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/util/qurl_util.py +1 -1
  73. qcanvas-2.0.0/qcanvas/util/ui_tools.py +155 -0
  74. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/util/url_checker.py +1 -1
  75. qcanvas-1.2.2/pyproject.toml +0 -57
  76. qcanvas-1.2.2/qcanvas/app_start/__init__.py +0 -59
  77. qcanvas-1.2.2/qcanvas/icons/_update_icons.py +0 -89
  78. qcanvas-1.2.2/qcanvas/icons/dark/actions/exit.svg +0 -3
  79. qcanvas-1.2.2/qcanvas/icons/dark/actions/mark_all_read.svg +0 -3
  80. qcanvas-1.2.2/qcanvas/icons/dark/actions/open_downloads.svg +0 -3
  81. qcanvas-1.2.2/qcanvas/icons/dark/actions/quick_login.svg +0 -3
  82. qcanvas-1.2.2/qcanvas/icons/dark/actions/sync.svg +0 -3
  83. qcanvas-1.2.2/qcanvas/icons/dark/branding/logo_transparent.svg +0 -303
  84. qcanvas-1.2.2/qcanvas/icons/dark/options/auto_download.svg +0 -3
  85. qcanvas-1.2.2/qcanvas/icons/dark/options/theme.svg +0 -3
  86. qcanvas-1.2.2/qcanvas/icons/dark/tabs/assignments.svg +0 -3
  87. qcanvas-1.2.2/qcanvas/icons/dark/tabs/mail.svg +0 -3
  88. qcanvas-1.2.2/qcanvas/icons/dark/tabs/pages.svg +0 -3
  89. qcanvas-1.2.2/qcanvas/icons/dark/tree_items/assignment.svg +0 -3
  90. qcanvas-1.2.2/qcanvas/icons/dark/tree_items/mail.svg +0 -3
  91. qcanvas-1.2.2/qcanvas/icons/dark/tree_items/module.svg +0 -3
  92. qcanvas-1.2.2/qcanvas/icons/dark/tree_items/page.svg +0 -3
  93. qcanvas-1.2.2/qcanvas/icons/icons.qrc +0 -46
  94. qcanvas-1.2.2/qcanvas/icons/light/actions/exit.svg +0 -3
  95. qcanvas-1.2.2/qcanvas/icons/light/actions/mark_all_read.svg +0 -3
  96. qcanvas-1.2.2/qcanvas/icons/light/actions/open_downloads.svg +0 -3
  97. qcanvas-1.2.2/qcanvas/icons/light/actions/quick_login.svg +0 -3
  98. qcanvas-1.2.2/qcanvas/icons/light/actions/sync.svg +0 -3
  99. qcanvas-1.2.2/qcanvas/icons/light/branding/logo_transparent.svg +0 -304
  100. qcanvas-1.2.2/qcanvas/icons/light/options/auto_download.svg +0 -3
  101. qcanvas-1.2.2/qcanvas/icons/light/options/ignore_old.svg +0 -3
  102. qcanvas-1.2.2/qcanvas/icons/light/options/include_videos.svg +0 -3
  103. qcanvas-1.2.2/qcanvas/icons/light/options/theme.svg +0 -3
  104. qcanvas-1.2.2/qcanvas/icons/light/tabs/assignments.svg +0 -3
  105. qcanvas-1.2.2/qcanvas/icons/light/tabs/mail.svg +0 -3
  106. qcanvas-1.2.2/qcanvas/icons/light/tabs/pages.svg +0 -3
  107. qcanvas-1.2.2/qcanvas/icons/light/tree_items/assignment.svg +0 -3
  108. qcanvas-1.2.2/qcanvas/icons/light/tree_items/mail.svg +0 -3
  109. qcanvas-1.2.2/qcanvas/icons/light/tree_items/module.svg +0 -3
  110. qcanvas-1.2.2/qcanvas/icons/light/tree_items/page.svg +0 -3
  111. qcanvas-1.2.2/qcanvas/icons/rc_icons.py +0 -2418
  112. qcanvas-1.2.2/qcanvas/icons/universal/branding/main_icon.svg +0 -325
  113. qcanvas-1.2.2/qcanvas/icons/universal/downloads/download_failed.svg +0 -23
  114. qcanvas-1.2.2/qcanvas/icons/universal/downloads/downloaded.svg +0 -23
  115. qcanvas-1.2.2/qcanvas/icons/universal/downloads/not_downloaded.svg +0 -23
  116. qcanvas-1.2.2/qcanvas/icons/universal/downloads/unknown.svg +0 -6
  117. qcanvas-1.2.2/qcanvas/icons/universal/tabs/assignments_new_content.svg +0 -3
  118. qcanvas-1.2.2/qcanvas/icons/universal/tabs/mail_new_content.svg +0 -3
  119. qcanvas-1.2.2/qcanvas/icons/universal/tabs/pages_new_content.svg +0 -3
  120. qcanvas-1.2.2/qcanvas/icons/universal/tree_items/semester.svg +0 -108
  121. qcanvas-1.2.2/qcanvas/ui/course_viewer/tabs/assignment_tab/assignment_tab.py +0 -68
  122. qcanvas-1.2.2/qcanvas/ui/course_viewer/tabs/mail_tab/mail_tab.py +0 -59
  123. qcanvas-1.2.2/qcanvas/ui/course_viewer/tabs/util.py +0 -11
  124. qcanvas-1.2.2/qcanvas/ui/main_ui/__init__.py +0 -0
  125. qcanvas-1.2.2/qcanvas/ui/memory_tree/_tree_memory.py +0 -67
  126. qcanvas-1.2.2/qcanvas/util/__init__.py +0 -0
  127. qcanvas-1.2.2/qcanvas/util/settings/__init__.py +0 -9
  128. qcanvas-1.2.2/qcanvas/util/themes/__init__.py +0 -2
  129. qcanvas-1.2.2/qcanvas/util/themes/_colour_scheme_helper.py +0 -38
  130. qcanvas-1.2.2/qcanvas/util/themes/_selected_theme.py +0 -10
  131. qcanvas-1.2.2/qcanvas/util/themes/_theme_changed_event.py +0 -17
  132. qcanvas-1.2.2/qcanvas/util/themes/_theme_changer.py +0 -86
  133. qcanvas-1.2.2/qcanvas/util/ui_tools.py +0 -45
  134. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/backend_connectors/__init__.py +0 -0
  135. {qcanvas-1.2.2/qcanvas → qcanvas-2.0.0/qcanvas/ui}/__init__.py +0 -0
  136. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/__init__.py +0 -0
  137. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/course_tree/__init__.py +0 -0
  138. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/__init__.py +0 -0
  139. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/assignment_tab/__init__.py +0 -0
  140. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/file_tab/__init__.py +0 -0
  141. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/mail_tab/__init__.py +0 -0
  142. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/course_viewer/tabs/page_tab/__init__.py +0 -0
  143. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/memory_tree/__init__.py +0 -0
  144. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.0/qcanvas/ui/qcanvas_window}/options/__init__.py +0 -0
  145. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/ui/setup/__init__.py +0 -0
  146. {qcanvas-1.2.2/qcanvas/ui → qcanvas-2.0.0/qcanvas/util}/__init__.py +0 -0
  147. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/util/html_cleaner.py +0 -0
  148. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/util/logs.py +0 -0
  149. {qcanvas-1.2.2 → qcanvas-2.0.0}/qcanvas/util/runtime.py +0 -0
@@ -1,21 +1,20 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: qcanvas
3
- Version: 1.2.2
3
+ Version: 2.0.0
4
4
  Summary: QCanvas is a desktop client for Canvas LMS.
5
5
  Author: QCanvas
6
6
  Author-email: QCanvas@noreply.codeberg.org
7
- Requires-Python: >3.11.0,<3.13
7
+ Requires-Python: >=3.12,<3.13
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3.12
10
+ Requires-Dist: aiofile (>=3.9.0,<4.0.0)
10
11
  Requires-Dist: aiosqlite (>=0.20.0,<0.21.0)
11
12
  Requires-Dist: asynctaskpool (>=0.2.1,<0.3.0)
12
- Requires-Dist: lightdb (>=2.0,<3.0)
13
+ Requires-Dist: cachetools (>=5.5.0,<6.0.0)
14
+ Requires-Dist: libqcanvas (>=0.5.1,<0.6.0)
13
15
  Requires-Dist: platformdirs (>=4.2.2,<5.0.0)
14
16
  Requires-Dist: pyqtdarktheme-fork (>=2.3.2,<3.0.0)
15
17
  Requires-Dist: qasync (>=0.27.1,<0.28.0)
16
- Requires-Dist: qcanvas-api-clients (>=0.4.0,<0.5.0)
17
- Requires-Dist: qcanvas-backend (>=0.3.0,<0.4.0)
18
- Requires-Dist: qtpy (>=2.4.1,<3.0.0)
19
18
  Requires-Dist: sqlalchemy (>=2.0.31,<3.0.0)
20
19
  Requires-Dist: validators (>=0.34.0,<0.35.0)
21
20
  Description-Content-Type: text/markdown
@@ -43,7 +42,7 @@ based distros.
43
42
 
44
43
  ## Prerequisites
45
44
 
46
- - Python 3.12+ (use [pyenv](https://github.com/pyenv/pyenv) if your distro does not have that version)
45
+ - Python 3.11+ (use [pyenv](https://github.com/pyenv/pyenv) if your distro does not have that version)
47
46
  - [Pipx](https://pipx.pypa.io/stable/) (optional)
48
47
  - Poetry (recommended to install using `pipx install poetry`)
49
48
  - [Appimagetool](https://github.com/AppImage/appimagetool) (Only for building the appimage)
@@ -57,15 +56,18 @@ cd QCanvasApp
57
56
  # Enter shell and run it
58
57
  poetry shell
59
58
  poetry install
60
- python qcanvas/run.py
59
+ python -m qcanvas
61
60
 
62
61
  # Alternatively you can run it like this:
63
62
  poetry install
64
- poetry run python qcanvas/run.py
63
+ poetry run python -m qcanvas
65
64
  ```
66
65
 
67
66
  ## Build custom AppImage
68
67
 
68
+ > [!INFO]
69
+ > This is not recommended as the appimage produced by this process isn't a proper appimage.
70
+
69
71
  ```bash
70
72
  bash build_appimage.sh
71
73
  ```
@@ -21,7 +21,7 @@ based distros.
21
21
 
22
22
  ## Prerequisites
23
23
 
24
- - Python 3.12+ (use [pyenv](https://github.com/pyenv/pyenv) if your distro does not have that version)
24
+ - Python 3.11+ (use [pyenv](https://github.com/pyenv/pyenv) if your distro does not have that version)
25
25
  - [Pipx](https://pipx.pypa.io/stable/) (optional)
26
26
  - Poetry (recommended to install using `pipx install poetry`)
27
27
  - [Appimagetool](https://github.com/AppImage/appimagetool) (Only for building the appimage)
@@ -35,15 +35,18 @@ cd QCanvasApp
35
35
  # Enter shell and run it
36
36
  poetry shell
37
37
  poetry install
38
- python qcanvas/run.py
38
+ python -m qcanvas
39
39
 
40
40
  # Alternatively you can run it like this:
41
41
  poetry install
42
- poetry run python qcanvas/run.py
42
+ poetry run python -m qcanvas
43
43
  ```
44
44
 
45
45
  ## Build custom AppImage
46
46
 
47
+ > [!INFO]
48
+ > This is not recommended as the appimage produced by this process isn't a proper appimage.
49
+
47
50
  ```bash
48
51
  bash build_appimage.sh
49
52
  ```
@@ -0,0 +1,57 @@
1
+ [tool.poetry]
2
+ name = "qcanvas"
3
+ version = "2.0.0"
4
+ description = "QCanvas is a desktop client for Canvas LMS."
5
+ authors = ["QCanvas <QCanvas@noreply.codeberg.org>"]
6
+ readme = "README.md"
7
+ exclude = [
8
+ "images",
9
+ "deploy",
10
+ "qcanvas/icons/*/*/*.svg",
11
+ "qcanvas/icons/_update_icons.py",
12
+ ]
13
+
14
+ [tool.poetry.scripts]
15
+ qcanvas = "qcanvas:main"
16
+
17
+ [tool.poetry.dependencies]
18
+ python = ">=3.12,<3.13"
19
+ libqcanvas = "^0.5.1"
20
+ #libqcanvas = { path = "../libqcanvas/", develop = true }
21
+ #libqcanvas-clients = { path = "../libqcanvas_clients/", develop = true }
22
+ asynctaskpool = "^0.2.1"
23
+ sqlalchemy = "^2.0.31"
24
+ aiosqlite = "^0.20.0"
25
+ pyqtdarktheme-fork = "^2.3.2"
26
+ qasync = "^0.27.1"
27
+ platformdirs = "^4.2.2"
28
+ validators = "^0.34.0"
29
+ cachetools = "^5.5.0"
30
+ aiofile = "^3.9.0"
31
+
32
+ [tool.poetry.group.flatpak-exclude.dependencies]
33
+ pyside6-essentials = "^6.8.0"
34
+ shiboken6 = "6.8.1" # pinned because latest release is ONLY a macos version for some reason
35
+ setuptools = "^71.1.0"
36
+ pyinstaller = "^6.10.0"
37
+
38
+ [tool.poetry.group.dev-tools]
39
+ optional = true
40
+
41
+ [tool.poetry.group.dev-tools.dependencies]
42
+ #nuitka = "^2.4.5"
43
+ rich = "^13.7.1"
44
+ pre-commit = "^4.0.1"
45
+ xmltodict = "^0.13.0"
46
+ mako = "^1.3.8"
47
+ invoke = "^2.2.0"
48
+
49
+ [build-system]
50
+ requires = ["poetry-core"]
51
+ build-backend = "poetry.core.masonry.api"
52
+
53
+ [tool.ruff.lint.per-file-ignores]
54
+ "__init__.py" = ["F401"]
55
+
56
+ [tool.ruff.lint.isort]
57
+ known-first-party = ["libqcanvas_clients", "asynctaskpool", "libqcanvas"]
@@ -25,30 +25,30 @@
25
25
  import logging
26
26
  from logging import INFO, WARNING
27
27
 
28
- import qcanvas.app_start
28
+ import qcanvas.app as app
29
29
  from qcanvas.util import logs, paths
30
30
 
31
- paths.data_storage().mkdir(parents=True, exist_ok=True)
32
-
33
- logging.basicConfig(
34
- filemode="w",
35
- filename=paths.data_storage() / "debug.log",
36
- level="WARN",
37
- )
38
-
39
- logs.set_levels(
40
- {
41
- "qcanvas": INFO,
42
- "qcanvas.ui": WARNING,
43
- "qcanvas_backend": INFO,
44
- "qcanvas.ui.main_ui.status_bar_progress_display": INFO,
45
- }
46
- )
47
-
48
31
 
49
32
  def main():
50
- qcanvas.app_start.launch()
33
+ app.launch()
51
34
 
52
35
 
53
36
  if __name__ == "__main__":
37
+ paths.data_storage().mkdir(parents=True, exist_ok=True)
38
+
39
+ logging.basicConfig(
40
+ filemode="w",
41
+ filename=paths.data_storage() / "debug.log",
42
+ level="WARN",
43
+ )
44
+
45
+ logs.set_levels(
46
+ {
47
+ "qcanvas": INFO,
48
+ "qcanvas.ui": WARNING,
49
+ "libqcanvas": INFO,
50
+ "qcanvas.ui.main_ui.status_bar_progress_display": INFO,
51
+ }
52
+ )
53
+
54
54
  main()
@@ -0,0 +1,93 @@
1
+ import asyncio
2
+ import logging
3
+ import sys
4
+
5
+ from libqcanvas.qcanvas import QCanvas
6
+ from PySide6.QtCore import QObject, Signal, Qt
7
+ from PySide6.QtGui import QGuiApplication
8
+ from PySide6.QtWidgets import QApplication
9
+ from qasync import QEventLoop, asyncSlot
10
+
11
+ import qcanvas.backend_connectors.qcanvas_task_master as task_master
12
+ from qcanvas.backend_connectors import FrontendResourceManager
13
+ from qcanvas.ui.qcanvas_window import QCanvasWindow
14
+ from qcanvas.ui.setup import SetupDialog, setup_checker
15
+ from qcanvas.util import paths, runtime
16
+ from qcanvas.theme import app_theme
17
+ import qcanvas.settings as settings
18
+
19
+ _logger = logging.getLogger(__name__)
20
+ app = QApplication(sys.argv)
21
+
22
+
23
+ # I couldn't figure out a reliable way of getting the event loop started.
24
+ # This just uses a signal with an async slot to run some async functions and then shows the main window
25
+ class _MainStarter(QObject):
26
+ _starting = Signal()
27
+
28
+ def __init__(self):
29
+ super().__init__()
30
+ self._starting.connect(self._start, Qt.ConnectionType.SingleShotConnection)
31
+
32
+ def start(self):
33
+ self._starting.emit()
34
+
35
+ @asyncSlot()
36
+ async def _start(self):
37
+ _qcanvas = await self._setup_database()
38
+
39
+ _main_window = QCanvasWindow(_qcanvas)
40
+ _main_window.show()
41
+ self.setParent(_main_window)
42
+
43
+ async def _setup_database(self) -> QCanvas[FrontendResourceManager]:
44
+ _qcanvas = QCanvas[FrontendResourceManager](
45
+ canvas_config=settings.client.canvas_config,
46
+ panopto_config=settings.client.panopto_config,
47
+ storage_path=paths.data_storage(),
48
+ resource_manager_class=FrontendResourceManager,
49
+ )
50
+
51
+ await _qcanvas.database.upgrade()
52
+ await _qcanvas.init()
53
+
54
+ return _qcanvas
55
+
56
+
57
+ def run_setup():
58
+ event_loop = QEventLoop(app)
59
+ asyncio.set_event_loop(event_loop)
60
+
61
+ app_close_event = asyncio.Event()
62
+ app.aboutToQuit.connect(app_close_event.set, Qt.ConnectionType.SingleShotConnection)
63
+
64
+ setup_window = SetupDialog()
65
+ setup_window.show()
66
+
67
+ with event_loop:
68
+ event_loop.run_until_complete(app_close_event.wait())
69
+
70
+
71
+ def launch():
72
+ if runtime.is_running_as_flatpak:
73
+ QGuiApplication.setDesktopFileName("io.github.qcanvas.QCanvasApp")
74
+
75
+ app.setApplicationName("QCanvas")
76
+
77
+ task_master.register()
78
+ app_theme.theme = settings.ui.theme
79
+
80
+ if setup_checker.needs_setup():
81
+ run_setup()
82
+
83
+ event_loop = QEventLoop(app)
84
+ asyncio.set_event_loop(event_loop)
85
+
86
+ app_close_event = asyncio.Event()
87
+ app.aboutToQuit.connect(app_close_event.set, Qt.ConnectionType.SingleShotConnection)
88
+
89
+ _main = _MainStarter()
90
+ _main.start()
91
+
92
+ with event_loop:
93
+ event_loop.run_until_complete(app_close_event.wait())
@@ -2,11 +2,14 @@ import logging
2
2
  from abc import ABCMeta
3
3
  from pathlib import Path
4
4
 
5
- import qcanvas_backend.database.types as db
6
- from qcanvas_backend.database import QCanvasDatabase
7
- from qcanvas_backend.net.resources.download.resource_manager import ResourceManager
8
- from qcanvas_backend.net.resources.extracting.extractors import Extractors
9
- from qtpy.QtCore import QObject, Signal
5
+ from PySide6.QtGui import QDesktopServices
6
+ from libqcanvas import db
7
+ from libqcanvas.database import QCanvasDatabase
8
+ from libqcanvas.net.resources.download.resource_manager import ResourceManager
9
+ from libqcanvas.net.resources.extracting.extractors import Extractors
10
+ from PySide6.QtCore import QObject, Signal
11
+
12
+ from qcanvas.util.qurl_util import file_url
10
13
 
11
14
  _logger = logging.getLogger(__name__)
12
15
 
@@ -29,6 +32,11 @@ class FrontendResourceManager(QObject, ResourceManager, metaclass=_Meta):
29
32
  database=database, download_dest=download_dest, extractors=extractors
30
33
  )
31
34
 
35
+ async def download_and_open(self, resource: db.Resource) -> None:
36
+ await self.download(resource)
37
+ resource_path = file_url(self.resource_download_location(resource))
38
+ QDesktopServices.openUrl(resource_path)
39
+
32
40
  def on_download_progress(
33
41
  self, resource: db.Resource, current: int, total: int
34
42
  ) -> None:
@@ -1,8 +1,8 @@
1
1
  import logging
2
2
  from abc import ABCMeta
3
3
 
4
- from qcanvas_backend.task_master import TaskID, TaskMaster, set_global_task_master
5
- from qtpy.QtCore import QObject, Signal
4
+ from libqcanvas.task_master import TaskID, TaskMaster, set_global_task_master
5
+ from PySide6.QtCore import QObject, Signal
6
6
 
7
7
  _logger = logging.getLogger(__name__)
8
8
 
@@ -1,9 +1,8 @@
1
- from qtpy.QtGui import QIcon
2
-
3
- from ._icon_type import ThemeIcon, UniversalIcon
4
1
  from .rc_icons import (
5
- qt_resource_data as _, # Without this, icon data will not be loaded
6
- )
2
+ qt_resource_data as _,
3
+ ) # Without this, icon data will not be loaded
4
+ from ._icon_type import UniversalIcon, ThemeIcon
5
+ from PySide6.QtGui import QIcon
7
6
 
8
7
 
9
8
  # noinspection PyPep8Naming
@@ -26,6 +25,7 @@ class options:
26
25
  auto_download = QIcon.fromTheme("options/auto_download")
27
26
  ignore_old = QIcon.fromTheme("options/ignore_old")
28
27
  include_videos = QIcon.fromTheme("options/include_videos")
28
+ sync_on_start = QIcon.fromTheme("options/sync_on_start")
29
29
  theme = QIcon.fromTheme("options/theme")
30
30
 
31
31
 
@@ -1,7 +1,7 @@
1
1
  # Unused
2
2
  import logging
3
3
 
4
- from qtpy.QtGui import QIcon
4
+ from PySide6.QtGui import QIcon
5
5
 
6
6
  _logger = logging.getLogger(__name__)
7
7
 
@@ -0,0 +1,50 @@
1
+ <!DOCTYPE RCC>
2
+ <RCC version="1.0">
3
+ <qresource prefix="icons/">
4
+ <file>dark/actions/exit.svg</file>
5
+ <file>dark/actions/mark_all_read.svg</file>
6
+ <file>dark/actions/open_downloads.svg</file>
7
+ <file>dark/actions/quick_login.svg</file>
8
+ <file>dark/actions/sync.svg</file>
9
+ <file>dark/branding/logo_transparent.svg</file>
10
+ <file>dark/options/auto_download.svg</file>
11
+ <file>dark/options/ignore_old.svg</file>
12
+ <file>dark/options/include_videos.svg</file>
13
+ <file>dark/options/sync_on_start.svg</file>
14
+ <file>dark/options/theme.svg</file>
15
+ <file>dark/tabs/assignments.svg</file>
16
+ <file>dark/tabs/mail.svg</file>
17
+ <file>dark/tabs/pages.svg</file>
18
+ <file>dark/tree_items/assignment.svg</file>
19
+ <file>dark/tree_items/mail.svg</file>
20
+ <file>dark/tree_items/module.svg</file>
21
+ <file>dark/tree_items/page.svg</file>
22
+ <file>light/actions/exit.svg</file>
23
+ <file>light/actions/mark_all_read.svg</file>
24
+ <file>light/actions/open_downloads.svg</file>
25
+ <file>light/actions/quick_login.svg</file>
26
+ <file>light/actions/sync.svg</file>
27
+ <file>light/branding/logo_transparent.svg</file>
28
+ <file>light/options/auto_download.svg</file>
29
+ <file>light/options/ignore_old.svg</file>
30
+ <file>light/options/include_videos.svg</file>
31
+ <file>light/options/sync_on_start.svg</file>
32
+ <file>light/options/theme.svg</file>
33
+ <file>light/tabs/assignments.svg</file>
34
+ <file>light/tabs/mail.svg</file>
35
+ <file>light/tabs/pages.svg</file>
36
+ <file>light/tree_items/assignment.svg</file>
37
+ <file>light/tree_items/mail.svg</file>
38
+ <file>light/tree_items/module.svg</file>
39
+ <file>light/tree_items/page.svg</file>
40
+ <file>universal/branding/main_icon.svg</file>
41
+ <file>universal/downloads/download_failed.svg</file>
42
+ <file>universal/downloads/downloaded.svg</file>
43
+ <file>universal/downloads/not_downloaded.svg</file>
44
+ <file>universal/downloads/unknown.svg</file>
45
+ <file>universal/tabs/assignments_new_content.svg</file>
46
+ <file>universal/tabs/mail_new_content.svg</file>
47
+ <file>universal/tabs/pages_new_content.svg</file>
48
+ <file>universal/tree_items/semester.svg</file>
49
+ </qresource>
50
+ </RCC>