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.

Files changed (63) hide show
  1. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/PKG-INFO +1 -1
  2. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/pyproject.toml +1 -1
  3. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/net/canvas/canvas_client.py +21 -0
  4. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/main_ui.py +19 -4
  5. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/course_indexer/data_manager.py +4 -4
  6. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/.gitignore +0 -0
  7. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/README.md +0 -0
  8. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/__init__.py +0 -0
  9. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/__main__.py +0 -0
  10. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/db/__init__.py +0 -0
  11. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/db/database.py +0 -0
  12. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/db/db_converter_helper.py +0 -0
  13. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/icons/__init__.py +0 -0
  14. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/icons/icons.qrc +0 -0
  15. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/icons/main_icon.svg +0 -0
  16. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/icons/rc_icons.py +0 -0
  17. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/net/__init__.py +0 -0
  18. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/net/canvas/__init__.py +0 -0
  19. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/net/canvas/legacy_canvas_types.py +0 -0
  20. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/net/custom_httpx_async_transport.py +0 -0
  21. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/net/self_authenticating.py +0 -0
  22. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/queries/__init__.py +0 -0
  23. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/queries/all_courses.gql +0 -0
  24. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/queries/all_courses.py +0 -0
  25. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/queries/canvas_course_data.gql +0 -0
  26. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/queries/canvas_course_data.py +0 -0
  27. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/__init__.py +0 -0
  28. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/container_item.py +0 -0
  29. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/menu_bar/__init__.py +0 -0
  30. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/menu_bar/grouping_preferences_menu.py +0 -0
  31. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/menu_bar/theme_selection_menu.py +0 -0
  32. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/setup_dialog.py +0 -0
  33. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/status_bar_reporter.py +0 -0
  34. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/viewer/__init__.py +0 -0
  35. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/viewer/course_list.py +0 -0
  36. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/viewer/file_list.py +0 -0
  37. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/viewer/file_view_tab.py +0 -0
  38. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/ui/viewer/page_list_viewer.py +0 -0
  39. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/__init__.py +0 -0
  40. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/app_settings.py +0 -0
  41. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/constants.py +0 -0
  42. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/course_indexer/__init__.py +0 -0
  43. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/course_indexer/conversion_helpers.py +0 -0
  44. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/course_indexer/resource_helpers.py +0 -0
  45. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/download_pool.py +0 -0
  46. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/helpers/__init__.py +0 -0
  47. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/helpers/canvas_sanitiser.py +0 -0
  48. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/helpers/file_icon_helper.py +0 -0
  49. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/helpers/qaction_helper.py +0 -0
  50. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/helpers/theme_helper.py +0 -0
  51. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/linkscanner/__init__.py +0 -0
  52. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/linkscanner/canvas_link_scanner.py +0 -0
  53. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/linkscanner/canvas_media_object_scanner.py +0 -0
  54. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/linkscanner/dropbox_scanner.py +0 -0
  55. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/linkscanner/resource_scanner.py +0 -0
  56. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/progress_reporter.py +0 -0
  57. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/self_updater.py +0 -0
  58. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/task_pool.py +0 -0
  59. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/tree_util/__init__.py +0 -0
  60. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/tree_util/expanding_tree.py +0 -0
  61. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/tree_util/model_helpers.py +0 -0
  62. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/qcanvas/util/tree_util/tree_model.py +0 -0
  63. {qcanvas-0.0.5.1a0 → qcanvas-0.0.5.2a0}/requirements.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qcanvas
3
- Version: 0.0.5.1a0
3
+ Version: 0.0.5.2a0
4
4
  Summary: A canvas client
5
5
  Author: QCanvas
6
6
  Classifier: Operating System :: OS Independent
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name="qcanvas"
7
- version = "0.0.5.1a"
7
+ version = "0.0.5.2a"
8
8
  authors= [ {name="QCanvas"} ]
9
9
  description="A canvas client"
10
10
  requires-python=">=3.11,<=3.12"
@@ -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(ThemeSelectionMenu())
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._client = client
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._client.do_graphql_query(gql(queries.all_courses.DEFINITION), detailed=True))
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._client.get_file(file.m_id, course_id)
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._client.get_page(page.m_id, course_id)
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