qcanvas 0.0.5.1a0__tar.gz → 0.0.5.2a0__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.
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/PKG-INFO +1 -1
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/pyproject.toml +1 -1
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/net/canvas/canvas_client.py +21 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/main_ui.py +19 -4
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/course_indexer/data_manager.py +4 -4
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/.gitignore +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/README.md +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/__main__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/db/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/db/database.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/db/db_converter_helper.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/icons/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/icons/icons.qrc +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/icons/main_icon.svg +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/icons/rc_icons.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/net/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/net/canvas/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/net/canvas/legacy_canvas_types.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/net/custom_httpx_async_transport.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/net/self_authenticating.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/queries/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/queries/all_courses.gql +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/queries/all_courses.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/queries/canvas_course_data.gql +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/queries/canvas_course_data.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/container_item.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/menu_bar/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/menu_bar/grouping_preferences_menu.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/menu_bar/theme_selection_menu.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/setup_dialog.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/status_bar_reporter.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/viewer/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/viewer/course_list.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/viewer/file_list.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/viewer/file_view_tab.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/viewer/page_list_viewer.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/app_settings.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/constants.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/course_indexer/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/course_indexer/conversion_helpers.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/course_indexer/resource_helpers.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/download_pool.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/helpers/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/helpers/canvas_sanitiser.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/helpers/file_icon_helper.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/helpers/qaction_helper.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/helpers/theme_helper.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/linkscanner/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/linkscanner/canvas_link_scanner.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/linkscanner/canvas_media_object_scanner.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/linkscanner/dropbox_scanner.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/linkscanner/resource_scanner.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/progress_reporter.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/self_updater.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/task_pool.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/tree_util/__init__.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/tree_util/expanding_tree.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/tree_util/model_helpers.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/tree_util/tree_model.py +0 -0
- {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/requirements.txt +0 -0
|
@@ -132,6 +132,27 @@ class CanvasClient(SelfAuthenticating):
|
|
|
132
132
|
|
|
133
133
|
return LegacyFile.from_dict(json.loads(response.text))
|
|
134
134
|
|
|
135
|
+
@retry(
|
|
136
|
+
wait=wait_exponential(exp_base=1.2, max=10) + wait_random(0, 1),
|
|
137
|
+
retry=retry_if_exception_type(RatelimitedException),
|
|
138
|
+
stop=stop_after_attempt(8)
|
|
139
|
+
)
|
|
140
|
+
async def get_temp_session_link(self) -> str | None:
|
|
141
|
+
"""
|
|
142
|
+
Gets the link which will authenticate a browser/open canvas using a 'legacy session token'
|
|
143
|
+
Returns
|
|
144
|
+
-------
|
|
145
|
+
str | None
|
|
146
|
+
The url as a string if the request succeeded, None if it didn't
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
token_response = await self.client.get(self.canvas_url.join("login/session_token"), **self.get_headers())
|
|
150
|
+
|
|
151
|
+
if token_response.is_success:
|
|
152
|
+
return json.loads(token_response.text)["session_url"]
|
|
153
|
+
else:
|
|
154
|
+
return None
|
|
155
|
+
|
|
135
156
|
@retry(
|
|
136
157
|
stop=stop_after_attempt(3),
|
|
137
158
|
wait=wait_fixed(5) + wait_random(0, 1),
|
|
@@ -3,8 +3,8 @@ import sys
|
|
|
3
3
|
import traceback
|
|
4
4
|
from typing import Sequence, Optional
|
|
5
5
|
|
|
6
|
-
from PySide6.QtCore import Slot, Signal, Qt, QUrl
|
|
7
|
-
from PySide6.QtGui import QDesktopServices
|
|
6
|
+
from PySide6.QtCore import Slot, Signal, Qt, QUrl, QObject
|
|
7
|
+
from PySide6.QtGui import QDesktopServices, QKeySequence
|
|
8
8
|
from PySide6.QtWidgets import *
|
|
9
9
|
from qasync import asyncSlot
|
|
10
10
|
|
|
@@ -20,6 +20,7 @@ from qcanvas.util import self_updater
|
|
|
20
20
|
from qcanvas.util.app_settings import settings
|
|
21
21
|
from qcanvas.util.constants import app_name
|
|
22
22
|
from qcanvas.util.course_indexer import DataManager
|
|
23
|
+
from qcanvas.util.helpers.qaction_helper import create_qaction
|
|
23
24
|
|
|
24
25
|
_aux_settings = settings.auxiliary
|
|
25
26
|
_no_course_selected_text = "No course selected"
|
|
@@ -103,9 +104,11 @@ class AppMainWindow(QMainWindow):
|
|
|
103
104
|
def setup_menu_bar(self):
|
|
104
105
|
menu_bar = self.menuBar()
|
|
105
106
|
|
|
106
|
-
menu_bar.addMenu(
|
|
107
|
-
view_menu = menu_bar.addMenu("View")
|
|
107
|
+
app_menu: QMenu = menu_bar.addMenu("App")
|
|
108
|
+
view_menu: QMenu = menu_bar.addMenu("View")
|
|
108
109
|
|
|
110
|
+
app_menu.addAction(self.setup_quick_authentication_action(app_menu))
|
|
111
|
+
app_menu.addMenu(ThemeSelectionMenu())
|
|
109
112
|
view_menu.addMenu(self.setup_group_by_menu())
|
|
110
113
|
|
|
111
114
|
def setup_group_by_menu(self) -> QMenu:
|
|
@@ -115,6 +118,18 @@ class AppMainWindow(QMainWindow):
|
|
|
115
118
|
|
|
116
119
|
return file_grouping_menu
|
|
117
120
|
|
|
121
|
+
def setup_quick_authentication_action(self, parent: QObject):
|
|
122
|
+
return create_qaction(
|
|
123
|
+
name="Quick canvas login",
|
|
124
|
+
shortcut=QKeySequence("Ctrl+O"),
|
|
125
|
+
triggered=self.open_quick_auth_in_browser,
|
|
126
|
+
parent=parent
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
@asyncSlot()
|
|
130
|
+
async def open_quick_auth_in_browser(self):
|
|
131
|
+
QDesktopServices.openUrl(await self.data_manager.client.get_temp_session_link())
|
|
132
|
+
|
|
118
133
|
def closeEvent(self, event):
|
|
119
134
|
settings.geometry = self.saveGeometry()
|
|
120
135
|
settings.window_state = self.saveState()
|
|
@@ -83,7 +83,7 @@ class DataManager:
|
|
|
83
83
|
sessionmaker: AsyncSessionMaker,
|
|
84
84
|
link_scanners: Sequence[ResourceScanner]):
|
|
85
85
|
|
|
86
|
-
self.
|
|
86
|
+
self.client = client
|
|
87
87
|
self._link_scanners = link_scanners
|
|
88
88
|
self._session_maker = sessionmaker
|
|
89
89
|
|
|
@@ -188,7 +188,7 @@ class DataManager:
|
|
|
188
188
|
|
|
189
189
|
async def synchronize_with_canvas(self, progress_reporter: ProgressReporter = noop_reporter):
|
|
190
190
|
section = progress_reporter.section("Loading index", 0)
|
|
191
|
-
raw_query = (await self.
|
|
191
|
+
raw_query = (await self.client.do_graphql_query(gql(queries.all_courses.DEFINITION), detailed=True))
|
|
192
192
|
section.increment_progress()
|
|
193
193
|
|
|
194
194
|
await self.load_courses_data(queries.AllCoursesQueryData(**raw_query).all_courses, progress_reporter)
|
|
@@ -343,7 +343,7 @@ class DataManager:
|
|
|
343
343
|
Fetches information about the specified file from canvas
|
|
344
344
|
"""
|
|
345
345
|
_logger.debug(f"Fetching file (for module file) %s %s", file.m_id, file.display_name)
|
|
346
|
-
result = await self.
|
|
346
|
+
result = await self.client.get_file(file.m_id, course_id)
|
|
347
347
|
resource = db.convert_file(file, result.size)
|
|
348
348
|
resource.id = f"{canvas_resource_id_prefix}:{resource.id}"
|
|
349
349
|
resource.course_id = course_id
|
|
@@ -369,7 +369,7 @@ class DataManager:
|
|
|
369
369
|
|
|
370
370
|
try:
|
|
371
371
|
# Get the page
|
|
372
|
-
result = await self.
|
|
372
|
+
result = await self.client.get_page(page.m_id, course_id)
|
|
373
373
|
except BaseException as e:
|
|
374
374
|
# Handle any errors
|
|
375
375
|
_logger.error(e)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/linkscanner/canvas_media_object_scanner.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|