qcanvas 1.2.2__tar.gz → 2.0.1__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 (147) hide show
  1. {qcanvas-1.2.2 → qcanvas-2.0.1}/PKG-INFO +17 -14
  2. {qcanvas-1.2.2 → qcanvas-2.0.1}/README.md +11 -7
  3. qcanvas-2.0.1/pyproject.toml +57 -0
  4. qcanvas-1.2.2/qcanvas/run.py → qcanvas-2.0.1/qcanvas/__init__.py +19 -19
  5. qcanvas-2.0.1/qcanvas/app.py +93 -0
  6. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/backend_connectors/frontend_resource_manager.py +13 -5
  7. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/backend_connectors/qcanvas_task_master.py +2 -2
  8. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/icons/__init__.py +5 -5
  9. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/icons/_icon_type.py +1 -1
  10. qcanvas-2.0.1/qcanvas/icons/icons.qrc +50 -0
  11. qcanvas-2.0.1/qcanvas/icons/rc_icons.py +2519 -0
  12. qcanvas-2.0.1/qcanvas/settings/__init__.py +6 -0
  13. {qcanvas-1.2.2/qcanvas/util → qcanvas-2.0.1/qcanvas}/settings/_client_settings.py +4 -4
  14. qcanvas-2.0.1/qcanvas/settings/_course_settings.py +54 -0
  15. {qcanvas-1.2.2/qcanvas/util → qcanvas-2.0.1/qcanvas}/settings/_mapped_setting.py +2 -5
  16. {qcanvas-1.2.2/qcanvas/util → qcanvas-2.0.1/qcanvas}/settings/_ui_settings.py +4 -4
  17. qcanvas-2.0.1/qcanvas/theme.py +101 -0
  18. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/content_tree.py +9 -12
  19. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/course_tree/_course_icon_generator.py +3 -3
  20. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/course_tree/course_tree.py +9 -8
  21. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/course_viewer.py +35 -43
  22. qcanvas-2.0.1/qcanvas/ui/course_viewer/tabs/assignment_tab/assignment_tab.py +146 -0
  23. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/assignment_tab/assignment_tree.py +4 -4
  24. qcanvas-2.0.1/qcanvas/ui/course_viewer/tabs/constants.py +1 -0
  25. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/content_tab.py +33 -39
  26. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/file_tab/file_tab.py +4 -4
  27. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/file_tab/file_tree.py +7 -10
  28. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/file_tab/pages_file_tree.py +6 -7
  29. qcanvas-2.0.1/qcanvas/ui/course_viewer/tabs/mail_tab/mail_tab.py +82 -0
  30. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/mail_tab/mail_tree.py +7 -8
  31. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/page_tab/page_tab.py +3 -3
  32. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/page_tab/page_tree.py +5 -5
  33. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/resource_rich_browser.py +15 -21
  34. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tree_widget_data_item.py +1 -1
  35. qcanvas-2.0.1/qcanvas/ui/memory_tree/_tree_memory.py +70 -0
  36. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/memory_tree/memory_tree_widget.py +22 -18
  37. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/memory_tree/memory_tree_widget_item.py +3 -3
  38. qcanvas-2.0.1/qcanvas/ui/qcanvas_window/__init__.py +1 -0
  39. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.1/qcanvas/ui/qcanvas_window}/course_viewer_container.py +10 -10
  40. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.1/qcanvas/ui/qcanvas_window}/options/auto_download_resources_option.py +5 -5
  41. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.1/qcanvas/ui/qcanvas_window}/options/quick_sync_option.py +7 -6
  42. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.1/qcanvas/ui/qcanvas_window}/options/sync_on_start_option.py +7 -6
  43. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.1/qcanvas/ui/qcanvas_window}/options/theme_selection_menu.py +10 -10
  44. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.1/qcanvas/ui/qcanvas_window}/qcanvas_window.py +38 -33
  45. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.1/qcanvas/ui/qcanvas_window}/status_bar_progress_display.py +5 -6
  46. qcanvas-2.0.1/qcanvas/ui/qml_components/AttachmentsList.ui.qml +15 -0
  47. qcanvas-2.0.1/qcanvas/ui/qml_components/AttachmentsListDelegate.qml +77 -0
  48. qcanvas-2.0.1/qcanvas/ui/qml_components/AttachmentsListModel.qml +19 -0
  49. qcanvas-2.0.1/qcanvas/ui/qml_components/AttachmentsPane.qml +11 -0
  50. qcanvas-2.0.1/qcanvas/ui/qml_components/CommentsList.ui.qml +15 -0
  51. qcanvas-2.0.1/qcanvas/ui/qml_components/CommentsListDelegate.ui.qml +118 -0
  52. qcanvas-2.0.1/qcanvas/ui/qml_components/CommentsListModel.qml +56 -0
  53. qcanvas-2.0.1/qcanvas/ui/qml_components/CommentsPane.qml +11 -0
  54. qcanvas-2.0.1/qcanvas/ui/qml_components/DecoratedText.ui.qml +44 -0
  55. qcanvas-2.0.1/qcanvas/ui/qml_components/Spacer.ui.qml +7 -0
  56. qcanvas-2.0.1/qcanvas/ui/qml_components/ThemedRectangle.qml +53 -0
  57. qcanvas-2.0.1/qcanvas/ui/qml_components/__init__.py +3 -0
  58. qcanvas-2.0.1/qcanvas/ui/qml_components/attachments_pane.py +72 -0
  59. qcanvas-2.0.1/qcanvas/ui/qml_components/comments_pane.py +85 -0
  60. qcanvas-2.0.1/qcanvas/ui/qml_components/qml_bridge_types.py +95 -0
  61. qcanvas-2.0.1/qcanvas/ui/qml_components/qml_pane.py +22 -0
  62. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/setup/setup_checker.py +1 -1
  63. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/setup/setup_dialog.py +27 -10
  64. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/util/auto_downloader.py +9 -7
  65. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/util/basic_fonts.py +2 -2
  66. qcanvas-2.0.1/qcanvas/util/context_dict.py +12 -0
  67. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/util/file_icons.py +11 -19
  68. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/util/layouts.py +5 -7
  69. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/util/paths.py +17 -6
  70. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/util/qurl_util.py +1 -1
  71. qcanvas-2.0.1/qcanvas/util/ui_tools.py +155 -0
  72. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/util/url_checker.py +1 -1
  73. qcanvas-1.2.2/pyproject.toml +0 -57
  74. qcanvas-1.2.2/qcanvas/app_start/__init__.py +0 -59
  75. qcanvas-1.2.2/qcanvas/icons/_update_icons.py +0 -89
  76. qcanvas-1.2.2/qcanvas/icons/dark/actions/exit.svg +0 -3
  77. qcanvas-1.2.2/qcanvas/icons/dark/actions/mark_all_read.svg +0 -3
  78. qcanvas-1.2.2/qcanvas/icons/dark/actions/open_downloads.svg +0 -3
  79. qcanvas-1.2.2/qcanvas/icons/dark/actions/quick_login.svg +0 -3
  80. qcanvas-1.2.2/qcanvas/icons/dark/actions/sync.svg +0 -3
  81. qcanvas-1.2.2/qcanvas/icons/dark/branding/logo_transparent.svg +0 -303
  82. qcanvas-1.2.2/qcanvas/icons/dark/options/auto_download.svg +0 -3
  83. qcanvas-1.2.2/qcanvas/icons/dark/options/theme.svg +0 -3
  84. qcanvas-1.2.2/qcanvas/icons/dark/tabs/assignments.svg +0 -3
  85. qcanvas-1.2.2/qcanvas/icons/dark/tabs/mail.svg +0 -3
  86. qcanvas-1.2.2/qcanvas/icons/dark/tabs/pages.svg +0 -3
  87. qcanvas-1.2.2/qcanvas/icons/dark/tree_items/assignment.svg +0 -3
  88. qcanvas-1.2.2/qcanvas/icons/dark/tree_items/mail.svg +0 -3
  89. qcanvas-1.2.2/qcanvas/icons/dark/tree_items/module.svg +0 -3
  90. qcanvas-1.2.2/qcanvas/icons/dark/tree_items/page.svg +0 -3
  91. qcanvas-1.2.2/qcanvas/icons/icons.qrc +0 -46
  92. qcanvas-1.2.2/qcanvas/icons/light/actions/exit.svg +0 -3
  93. qcanvas-1.2.2/qcanvas/icons/light/actions/mark_all_read.svg +0 -3
  94. qcanvas-1.2.2/qcanvas/icons/light/actions/open_downloads.svg +0 -3
  95. qcanvas-1.2.2/qcanvas/icons/light/actions/quick_login.svg +0 -3
  96. qcanvas-1.2.2/qcanvas/icons/light/actions/sync.svg +0 -3
  97. qcanvas-1.2.2/qcanvas/icons/light/branding/logo_transparent.svg +0 -304
  98. qcanvas-1.2.2/qcanvas/icons/light/options/auto_download.svg +0 -3
  99. qcanvas-1.2.2/qcanvas/icons/light/options/ignore_old.svg +0 -3
  100. qcanvas-1.2.2/qcanvas/icons/light/options/include_videos.svg +0 -3
  101. qcanvas-1.2.2/qcanvas/icons/light/options/theme.svg +0 -3
  102. qcanvas-1.2.2/qcanvas/icons/light/tabs/assignments.svg +0 -3
  103. qcanvas-1.2.2/qcanvas/icons/light/tabs/mail.svg +0 -3
  104. qcanvas-1.2.2/qcanvas/icons/light/tabs/pages.svg +0 -3
  105. qcanvas-1.2.2/qcanvas/icons/light/tree_items/assignment.svg +0 -3
  106. qcanvas-1.2.2/qcanvas/icons/light/tree_items/mail.svg +0 -3
  107. qcanvas-1.2.2/qcanvas/icons/light/tree_items/module.svg +0 -3
  108. qcanvas-1.2.2/qcanvas/icons/light/tree_items/page.svg +0 -3
  109. qcanvas-1.2.2/qcanvas/icons/rc_icons.py +0 -2418
  110. qcanvas-1.2.2/qcanvas/icons/universal/branding/main_icon.svg +0 -325
  111. qcanvas-1.2.2/qcanvas/icons/universal/downloads/download_failed.svg +0 -23
  112. qcanvas-1.2.2/qcanvas/icons/universal/downloads/downloaded.svg +0 -23
  113. qcanvas-1.2.2/qcanvas/icons/universal/downloads/not_downloaded.svg +0 -23
  114. qcanvas-1.2.2/qcanvas/icons/universal/downloads/unknown.svg +0 -6
  115. qcanvas-1.2.2/qcanvas/icons/universal/tabs/assignments_new_content.svg +0 -3
  116. qcanvas-1.2.2/qcanvas/icons/universal/tabs/mail_new_content.svg +0 -3
  117. qcanvas-1.2.2/qcanvas/icons/universal/tabs/pages_new_content.svg +0 -3
  118. qcanvas-1.2.2/qcanvas/icons/universal/tree_items/semester.svg +0 -108
  119. qcanvas-1.2.2/qcanvas/ui/course_viewer/tabs/assignment_tab/assignment_tab.py +0 -68
  120. qcanvas-1.2.2/qcanvas/ui/course_viewer/tabs/mail_tab/mail_tab.py +0 -59
  121. qcanvas-1.2.2/qcanvas/ui/course_viewer/tabs/util.py +0 -11
  122. qcanvas-1.2.2/qcanvas/ui/main_ui/__init__.py +0 -0
  123. qcanvas-1.2.2/qcanvas/ui/memory_tree/_tree_memory.py +0 -67
  124. qcanvas-1.2.2/qcanvas/util/__init__.py +0 -0
  125. qcanvas-1.2.2/qcanvas/util/settings/__init__.py +0 -9
  126. qcanvas-1.2.2/qcanvas/util/themes/__init__.py +0 -2
  127. qcanvas-1.2.2/qcanvas/util/themes/_colour_scheme_helper.py +0 -38
  128. qcanvas-1.2.2/qcanvas/util/themes/_selected_theme.py +0 -10
  129. qcanvas-1.2.2/qcanvas/util/themes/_theme_changed_event.py +0 -17
  130. qcanvas-1.2.2/qcanvas/util/themes/_theme_changer.py +0 -86
  131. qcanvas-1.2.2/qcanvas/util/ui_tools.py +0 -45
  132. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/backend_connectors/__init__.py +0 -0
  133. {qcanvas-1.2.2/qcanvas → qcanvas-2.0.1/qcanvas/ui}/__init__.py +0 -0
  134. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/__init__.py +0 -0
  135. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/course_tree/__init__.py +0 -0
  136. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/__init__.py +0 -0
  137. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/assignment_tab/__init__.py +0 -0
  138. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/file_tab/__init__.py +0 -0
  139. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/mail_tab/__init__.py +0 -0
  140. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/course_viewer/tabs/page_tab/__init__.py +0 -0
  141. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/memory_tree/__init__.py +0 -0
  142. {qcanvas-1.2.2/qcanvas/ui/main_ui → qcanvas-2.0.1/qcanvas/ui/qcanvas_window}/options/__init__.py +0 -0
  143. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/ui/setup/__init__.py +0 -0
  144. {qcanvas-1.2.2/qcanvas/ui → qcanvas-2.0.1/qcanvas/util}/__init__.py +0 -0
  145. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/util/html_cleaner.py +0 -0
  146. {qcanvas-1.2.2 → qcanvas-2.0.1}/qcanvas/util/logs.py +0 -0
  147. {qcanvas-1.2.2 → qcanvas-2.0.1}/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.1
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
@@ -36,17 +35,15 @@ https://github.com/QCanvas/QCanvasApp
36
35
 
37
36
  You can download a **windows** version from [releases](https://github.com/QCanvas/QCanvasApp/releases)
38
37
 
39
- The appimage version is *not recommended* as it is not a proper portable appimage. It will only work on debian/ubuntu
40
- based distros.
38
+ > [!WARNING]
39
+ > The appimage version is *not recommended* as it is not a proper portable appimage. It will only work on debian/ubuntu based distros.
41
40
 
42
41
  # Development/Run from source
43
42
 
44
43
  ## Prerequisites
45
44
 
46
45
  - Python 3.12+ (use [pyenv](https://github.com/pyenv/pyenv) if your distro does not have that version)
47
- - [Pipx](https://pipx.pypa.io/stable/) (optional)
48
- - Poetry (recommended to install using `pipx install poetry`)
49
- - [Appimagetool](https://github.com/AppImage/appimagetool) (Only for building the appimage)
46
+ - Poetry
50
47
 
51
48
  ## Get started
52
49
 
@@ -57,15 +54,21 @@ cd QCanvasApp
57
54
  # Enter shell and run it
58
55
  poetry shell
59
56
  poetry install
60
- python qcanvas/run.py
57
+ python -m qcanvas
61
58
 
62
59
  # Alternatively you can run it like this:
63
60
  poetry install
64
- poetry run python qcanvas/run.py
61
+ poetry run python -m qcanvas
65
62
  ```
66
63
 
67
64
  ## Build custom AppImage
68
65
 
66
+ > [!WARNING]
67
+ > This is not recommended as the appimage produced by this process isn't a proper appimage.
68
+
69
+ > [!IMPORTANT]
70
+ > You will need [Appimagetool](https://github.com/AppImage/appimagetool)
71
+
69
72
  ```bash
70
73
  bash build_appimage.sh
71
74
  ```
@@ -14,17 +14,15 @@ https://github.com/QCanvas/QCanvasApp
14
14
 
15
15
  You can download a **windows** version from [releases](https://github.com/QCanvas/QCanvasApp/releases)
16
16
 
17
- The appimage version is *not recommended* as it is not a proper portable appimage. It will only work on debian/ubuntu
18
- based distros.
17
+ > [!WARNING]
18
+ > The appimage version is *not recommended* as it is not a proper portable appimage. It will only work on debian/ubuntu based distros.
19
19
 
20
20
  # Development/Run from source
21
21
 
22
22
  ## Prerequisites
23
23
 
24
24
  - Python 3.12+ (use [pyenv](https://github.com/pyenv/pyenv) if your distro does not have that version)
25
- - [Pipx](https://pipx.pypa.io/stable/) (optional)
26
- - Poetry (recommended to install using `pipx install poetry`)
27
- - [Appimagetool](https://github.com/AppImage/appimagetool) (Only for building the appimage)
25
+ - Poetry
28
26
 
29
27
  ## Get started
30
28
 
@@ -35,15 +33,21 @@ cd QCanvasApp
35
33
  # Enter shell and run it
36
34
  poetry shell
37
35
  poetry install
38
- python qcanvas/run.py
36
+ python -m qcanvas
39
37
 
40
38
  # Alternatively you can run it like this:
41
39
  poetry install
42
- poetry run python qcanvas/run.py
40
+ poetry run python -m qcanvas
43
41
  ```
44
42
 
45
43
  ## Build custom AppImage
46
44
 
45
+ > [!WARNING]
46
+ > This is not recommended as the appimage produced by this process isn't a proper appimage.
47
+
48
+ > [!IMPORTANT]
49
+ > You will need [Appimagetool](https://github.com/AppImage/appimagetool)
50
+
47
51
  ```bash
48
52
  bash build_appimage.sh
49
53
  ```
@@ -0,0 +1,57 @@
1
+ [tool.poetry]
2
+ name = "qcanvas"
3
+ version = "2.0.1"
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>