qcanvas 0.0.3.4a0__tar.gz → 0.0.4.1a0__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 (68) hide show
  1. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/PKG-INFO +1 -1
  2. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/pyproject.toml +1 -1
  3. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/QtVersionHelper/QtGui/__init__.py +1 -1
  4. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/QtVersionHelper/__init__.py +2 -1
  5. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/__main__.py +5 -9
  6. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/db/__init__.py +2 -1
  7. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/db/database.py +11 -4
  8. qcanvas-0.0.4.1a0/qcanvas/icons/__init__.py +1 -0
  9. qcanvas-0.0.4.1a0/qcanvas/icons/icons.qrc +6 -0
  10. qcanvas-0.0.4.1a0/qcanvas/icons/main_icon.svg +325 -0
  11. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/icons/rc_icons.py +3 -0
  12. qcanvas-0.0.4.1a0/qcanvas/net/canvas/__init__.py +2 -0
  13. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/net/canvas/canvas_client.py +4 -2
  14. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/net/canvas/legacy_canvas_types.py +2 -2
  15. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/net/custom_httpx_async_transport.py +2 -3
  16. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/net/self_authenticating.py +1 -0
  17. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/queries/all_courses.gql +3 -3
  18. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/queries/all_courses.py +2 -2
  19. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/queries/canvas_course_data.py +2 -2
  20. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/ui/container_item.py +0 -6
  21. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/ui/main_ui.py +34 -18
  22. qcanvas-0.0.4.1a0/qcanvas/ui/menu_bar/grouping_preferences_menu.py +61 -0
  23. qcanvas-0.0.4.1a0/qcanvas/ui/menu_bar/theme_selection_menu.py +36 -0
  24. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/ui/setup_dialog.py +3 -3
  25. qcanvas-0.0.4.1a0/qcanvas/ui/viewer/__init__.py +0 -0
  26. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/ui/viewer/course_list.py +1 -3
  27. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/ui/viewer/file_list.py +1 -3
  28. qcanvas-0.0.4.1a0/qcanvas/ui/viewer/file_view_tab.py +61 -0
  29. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/__init__.py +1 -1
  30. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/app_settings.py +28 -2
  31. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/constants.py +1 -1
  32. qcanvas-0.0.4.1a0/qcanvas/util/course_indexer/__init__.py +1 -0
  33. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/course_indexer/data_manager.py +8 -4
  34. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/course_indexer/resource_helpers.py +2 -1
  35. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/file_icon_helper.py +2 -1
  36. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/linkscanner/canvas_media_object_scanner.py +2 -2
  37. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/self_updater.py +6 -6
  38. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/task_pool.py +1 -1
  39. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/tree_util/model_helpers.py +1 -1
  40. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/tree_util/tree_model.py +1 -0
  41. qcanvas-0.0.3.4a0/qcanvas/icons/__init__.py +0 -1
  42. qcanvas-0.0.3.4a0/qcanvas/icons/icons.qrc +0 -5
  43. qcanvas-0.0.3.4a0/qcanvas/icons/main_icon.svg +0 -312
  44. qcanvas-0.0.3.4a0/qcanvas/net/canvas/__init__.py +0 -2
  45. qcanvas-0.0.3.4a0/qcanvas/ui/viewer/file_view_tab.py +0 -122
  46. qcanvas-0.0.3.4a0/qcanvas/util/course_indexer/__init__.py +0 -1
  47. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/.gitignore +0 -0
  48. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/README.md +0 -0
  49. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/QtVersionHelper/QtCore/__init__.py +0 -0
  50. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/QtVersionHelper/QtWidgets/__init__.py +0 -0
  51. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/__init__.py +0 -0
  52. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/db/db_converter_helper.py +0 -0
  53. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/net/__init__.py +0 -0
  54. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/queries/__init__.py +0 -0
  55. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/queries/canvas_course_data.gql +0 -0
  56. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/ui/__init__.py +0 -0
  57. {qcanvas-0.0.3.4a0/qcanvas/ui/viewer → qcanvas-0.0.4.1a0/qcanvas/ui/menu_bar}/__init__.py +0 -0
  58. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/ui/viewer/page_list_viewer.py +0 -0
  59. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/canvas_garbage_remover.py +0 -0
  60. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/course_indexer/conversion_helpers.py +0 -0
  61. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/download_pool.py +0 -0
  62. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/linkscanner/__init__.py +0 -0
  63. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/linkscanner/canvas_link_scanner.py +0 -0
  64. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/linkscanner/dropbox_scanner.py +0 -0
  65. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/linkscanner/resource_scanner.py +1 -1
  66. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/tree_util/__init__.py +0 -0
  67. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/qcanvas/util/tree_util/expanding_tree.py +0 -0
  68. {qcanvas-0.0.3.4a0 → qcanvas-0.0.4.1a0}/requirements.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qcanvas
3
- Version: 0.0.3.4a0
3
+ Version: 0.0.4.1a0
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.3.4a"
7
+ version="0.0.4.1a"
8
8
  authors= [ {name="QCanvas"} ]
9
9
  description="A canvas client"
10
10
  requires-python=">=3.11,<=3.12"
@@ -15,7 +15,7 @@ elif QT_VERSION == 6:
15
15
 
16
16
 
17
17
  def create_qaction(name: str, shortcut: QKeySequence | None = None, parent: Any = None, triggered: Any = None,
18
- checkable: bool | None = None, checked : bool | None = None) -> QAction:
18
+ checkable: bool | None = None, checked: bool | None = None) -> QAction:
19
19
  action = QAction(name)
20
20
 
21
21
  if shortcut is not None:
@@ -2,6 +2,7 @@ import sys
2
2
 
3
3
  QT_VERSION = 6
4
4
 
5
+
5
6
  # if sys.modules.get("PySide6.QtCore"):
6
7
  # QT_VERSION = 6
7
8
  # elif sys.modules.get("PySide2.QtCore"):
@@ -17,4 +18,4 @@ def run_app(app):
17
18
  if sys.modules.get("PySide6.QtCore"):
18
19
  return app.exec()
19
20
  else:
20
- return app.exec_()
21
+ return app.exec_()
@@ -4,15 +4,16 @@ import sys
4
4
  from datetime import datetime
5
5
 
6
6
  import httpx
7
- import qdarktheme
8
7
  from httpx import URL
9
8
  from qasync import QEventLoop, asyncSlot
10
9
  from sqlalchemy.ext.asyncio import create_async_engine
11
10
  from sqlalchemy.ext.asyncio.session import async_sessionmaker as AsyncSessionMaker
12
11
 
13
12
  import qcanvas.db as db
14
- from qcanvas.QtVersionHelper.QtGui import QPixmap
13
+ # noinspection PyUnresolvedReferences
14
+ import qcanvas.icons
15
15
  from qcanvas.QtVersionHelper.QtCore import Signal
16
+ from qcanvas.QtVersionHelper.QtGui import QPixmap
16
17
  from qcanvas.QtVersionHelper.QtWidgets import QApplication, QProgressDialog, QMainWindow
17
18
  from qcanvas.net.canvas.canvas_client import CanvasClient
18
19
  from qcanvas.ui.main_ui import AppMainWindow
@@ -24,14 +25,12 @@ from qcanvas.util.linkscanner import CanvasFileScanner
24
25
  from qcanvas.util.linkscanner.canvas_media_object_scanner import CanvasMediaObjectScanner
25
26
  from qcanvas.util.linkscanner.dropbox_scanner import DropboxScanner
26
27
 
27
- # noinspection PyUnresolvedReferences
28
- import qcanvas.icons
29
-
30
28
  engine = create_async_engine("sqlite+aiosqlite:///canvas_db.😘", echo=False)
31
29
 
32
30
  logging.basicConfig()
33
31
  logging.getLogger("canvas_client").setLevel(logging.DEBUG)
34
32
 
33
+
35
34
  async def begin():
36
35
  # Create meta stuff
37
36
  async with engine.begin() as conn:
@@ -55,7 +54,6 @@ class LoaderWindow(QMainWindow):
55
54
 
56
55
  self.init.emit()
57
56
 
58
-
59
57
  @asyncSlot()
60
58
  async def on_init(self):
61
59
  try:
@@ -103,9 +101,7 @@ if __name__ == '__main__':
103
101
 
104
102
  app = QApplication(sys.argv)
105
103
 
106
- qdarktheme.setup_theme("light",
107
- custom_colors={"primary": "FF804F"}
108
- )
104
+ AppSettings.apply_selected_theme()
109
105
 
110
106
  event_loop = QEventLoop()
111
107
  asyncio.set_event_loop(event_loop)
@@ -1,4 +1,5 @@
1
1
  from .database import Resource, Module, ModuleItem, ModulePage, ModuleFile, ResourceState, Course, Term, \
2
- Assignment, Base, PageLike, ResourceToModuleItemAssociation, ResourceToAssignmentAssociation, CoursePreferences, GroupByPreference
2
+ Assignment, Base, PageLike, ResourceToModuleItemAssociation, ResourceToAssignmentAssociation, CoursePreferences, \
3
+ GroupByPreference
3
4
  from .db_converter_helper import convert_course, convert_page, convert_file, convert_legacy_file, \
4
5
  convert_assignment, convert_module, convert_term, convert_file_page
@@ -57,6 +57,7 @@ class GroupByPreference(Enum):
57
57
  GROUP_BY_PAGES = 0
58
58
  GROUP_BY_MODULES = 1
59
59
 
60
+
60
61
  class CoursePreferences(Base):
61
62
  __tablename__ = "preferences"
62
63
 
@@ -86,6 +87,7 @@ class Course(MappedAsDataclass, Base, init=False):
86
87
  assignments: Mapped[List["Assignment"]] = relationship(back_populates="course")
87
88
  resources: Mapped[List["Resource"]] = relationship(back_populates="course")
88
89
 
90
+
89
91
  class Term(MappedAsDataclass, Base):
90
92
  """
91
93
  A term object.
@@ -162,9 +164,12 @@ class ResourceState(Enum):
162
164
  @staticmethod
163
165
  def human_readable(value: "ResourceState"):
164
166
  match value:
165
- case ResourceState.NOT_DOWNLOADED: return "Not downloaded"
166
- case ResourceState.DOWNLOADED: return "Downloaded"
167
- case ResourceState.FAILED: return "Failed"
167
+ case ResourceState.NOT_DOWNLOADED:
168
+ return "Not downloaded"
169
+ case ResourceState.DOWNLOADED:
170
+ return "Downloaded"
171
+ case ResourceState.FAILED:
172
+ return "Failed"
168
173
 
169
174
  raise ValueError(value)
170
175
 
@@ -220,12 +225,14 @@ class Resource(MappedAsDataclass, Base, tree.HasText):
220
225
 
221
226
  file_name, file_extension = os.path.splitext(self.file_name)
222
227
 
223
- return pathlib.Path("download", self._sanitise_course_name(self.course.name), f"{file_name} [{file_id}]{file_extension}")
228
+ return pathlib.Path("download", self._sanitise_course_name(self.course.name),
229
+ f"{file_name} [{file_id}]{file_extension}")
224
230
 
225
231
  @staticmethod
226
232
  def _sanitise_course_name(name: str) -> str:
227
233
  return re.sub("[/\\\\<>:\"?|*]", "_", name)
228
234
 
235
+
229
236
  class ModuleItem(MappedAsDataclass, Base, tree.HasText):
230
237
  __tablename__ = "module_items"
231
238
 
@@ -0,0 +1 @@
1
+ from qcanvas.icons import rc_icons
@@ -0,0 +1,6 @@
1
+ <!DOCTYPE RCC>
2
+ <RCC version="1.0">
3
+ <qresource>
4
+ <file>main_icon.svg</file>
5
+ </qresource>
6
+ </RCC>
@@ -0,0 +1,325 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+ <svg
5
+ inkscape:export-ydpi="90.000000"
6
+ inkscape:export-xdpi="90.000000"
7
+ width="256"
8
+ height="256"
9
+ id="svg11300"
10
+ sodipodi:version="0.32"
11
+ inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
12
+ sodipodi:docname="icon.svg"
13
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
14
+ version="1.0"
15
+ style="display:inline;enable-background:new"
16
+ inkscape:export-filename="/home/sam/moka-next-template.png"
17
+ xml:space="preserve"
18
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
19
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
20
+ xmlns:xlink="http://www.w3.org/1999/xlink"
21
+ xmlns="http://www.w3.org/2000/svg"
22
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
23
+ xmlns:cc="http://creativecommons.org/ns#"
24
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><sodipodi:namedview
25
+ stroke="#ef2929"
26
+ fill="#f57900"
27
+ id="base"
28
+ pagecolor="#777777"
29
+ bordercolor="#666666"
30
+ borderopacity="0.25490196"
31
+ inkscape:pageopacity="0"
32
+ inkscape:pageshadow="2"
33
+ inkscape:zoom="2"
34
+ inkscape:cx="246.75"
35
+ inkscape:cy="112.75"
36
+ inkscape:current-layer="layer7"
37
+ showgrid="false"
38
+ inkscape:grid-bbox="true"
39
+ inkscape:document-units="px"
40
+ inkscape:showpageshadow="false"
41
+ inkscape:window-width="1920"
42
+ inkscape:window-height="1018"
43
+ inkscape:window-x="1920"
44
+ inkscape:window-y="0"
45
+ width="400px"
46
+ height="300px"
47
+ inkscape:snap-nodes="true"
48
+ inkscape:snap-bbox="true"
49
+ gridtolerance="10000"
50
+ inkscape:object-nodes="true"
51
+ inkscape:snap-grids="true"
52
+ showguides="true"
53
+ inkscape:guide-bbox="true"
54
+ inkscape:window-maximized="1"
55
+ inkscape:bbox-nodes="true"
56
+ inkscape:bbox-paths="true"
57
+ inkscape:snap-bbox-edge-midpoints="true"
58
+ inkscape:snap-bbox-midpoints="true"
59
+ inkscape:pagecheckerboard="0"
60
+ inkscape:deskcolor="#d1d1d1"><inkscape:grid
61
+ spacingy="1px"
62
+ spacingx="1px"
63
+ id="grid5883"
64
+ type="xygrid"
65
+ enabled="true"
66
+ visible="false"
67
+ empspacing="4"
68
+ snapvisiblegridlinesonly="true"
69
+ dotted="false"
70
+ color="#000000"
71
+ opacity="0.12549"
72
+ empcolor="#203ef3"
73
+ empopacity="0.36470588"
74
+ originx="-16"
75
+ originy="-28"
76
+ units="px" /><inkscape:grid
77
+ type="xygrid"
78
+ id="grid11592"
79
+ empspacing="8"
80
+ visible="false"
81
+ enabled="false"
82
+ spacingx="0.5px"
83
+ spacingy="0.5px"
84
+ color="#ff0000"
85
+ opacity="0.12549"
86
+ empcolor="#ff0000"
87
+ empopacity="0.25098039"
88
+ snapvisiblegridlinesonly="true"
89
+ dotted="true"
90
+ originx="-16"
91
+ originy="-28"
92
+ units="px"/></sodipodi:namedview>
93
+ <defs
94
+ id="defs3"><linearGradient
95
+ inkscape:collect="always"
96
+ xlink:href="#outerBackgroundGradient-2"
97
+ id="linearGradient4254"
98
+ x1="35"
99
+ y1="156"
100
+ x2="253"
101
+ y2="156"
102
+ gradientUnits="userSpaceOnUse"
103
+ gradientTransform="rotate(-90,144,156)" />
104
+ <linearGradient
105
+ id="outerBackgroundGradient-2"><stop
106
+ style="stop-color:#e70a0a;stop-opacity:1;"
107
+ offset="0"
108
+ id="stop3864-8-6-00" />
109
+ <stop
110
+ style="stop-color:#fe0000;stop-opacity:1;"
111
+ offset="1"
112
+ id="stop3866-9-1-1"/></linearGradient>
113
+ <style
114
+ id="style1">.cls-1{fill:#fff;}</style></defs>
115
+ <metadata
116
+ id="metadata4"><rdf:RDF><cc:Work
117
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
118
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:creator><cc:Agent><dc:title>Sam Hewitt</dc:title></cc:Agent></dc:creator><dc:source/><cc:license
119
+ rdf:resource=""/><dc:title/><dc:subject><rdf:Bag /></dc:subject><dc:date/><dc:rights><cc:Agent><dc:title /></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title /></cc:Agent></dc:publisher><dc:identifier/><dc:relation/><dc:language/><dc:coverage/><dc:description/><dc:contributor><cc:Agent><dc:title /></cc:Agent></dc:contributor></cc:Work><cc:Work
120
+ rdf:about=""><dc:format>image/svg+xml</dc:format>
121
+ <dc:type
122
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata>
123
+ <g
124
+ style="display:inline"
125
+ inkscape:groupmode="layer"
126
+ inkscape:label="Icon"
127
+ id="layer1"
128
+ transform="translate(-16,-28)"><g
129
+ style="display:none"
130
+ inkscape:label="Baseplate"
131
+ id="layer7"
132
+ inkscape:groupmode="layer"><text
133
+ y="19.745117"
134
+ xml:space="preserve"
135
+ x="15.006836"
136
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';display:inline;fill:#000000;fill-opacity:1;stroke:none;enable-background:new"
137
+ inkscape:label="context"
138
+ id="context"><tspan
139
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans'"
140
+ y="19.745117"
141
+ x="15.006836"
142
+ sodipodi:role="line"
143
+ id="tspan3933">apps</tspan></text><text
144
+ y="19.745117"
145
+ xml:space="preserve"
146
+ x="122.48828"
147
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none;enable-background:new"
148
+ inkscape:label="icon-name"
149
+ id="icon-name"><tspan
150
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:18px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold'"
151
+ y="19.745117"
152
+ x="122.48828"
153
+ sodipodi:role="line"
154
+ id="tspan3937">amd</tspan></text><rect
155
+ style="display:inline;overflow:visible;visibility:visible;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
156
+ id="rect16x16"
157
+ width="16"
158
+ height="16"
159
+ x="416"
160
+ y="140"
161
+ inkscape:label="16x16"/><rect
162
+ style="display:inline;overflow:visible;visibility:visible;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
163
+ id="rect24x24"
164
+ width="24"
165
+ height="24"
166
+ x="416"
167
+ y="100"
168
+ inkscape:label="24x24"/><rect
169
+ style="display:inline;overflow:visible;visibility:visible;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
170
+ id="rect32x32"
171
+ width="32"
172
+ height="32"
173
+ x="416"
174
+ y="52"
175
+ inkscape:label="32x32"/><rect
176
+ inkscape:label="22x22"
177
+ y="101"
178
+ x="417"
179
+ height="22"
180
+ width="22"
181
+ id="rect22x22"
182
+ style="display:inline;overflow:visible;visibility:visible;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"/><rect
183
+ inkscape:label="48x48"
184
+ y="220"
185
+ x="288"
186
+ height="48"
187
+ width="48"
188
+ id="rect48x48"
189
+ style="display:inline;overflow:visible;visibility:visible;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"/><rect
190
+ style="display:inline;overflow:visible;visibility:visible;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
191
+ id="rect256x256"
192
+ width="256"
193
+ height="256"
194
+ x="16"
195
+ y="28"
196
+ inkscape:label="256x256"/><rect
197
+ style="display:inline;overflow:visible;visibility:visible;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
198
+ id="rect64x64"
199
+ width="64"
200
+ height="64"
201
+ x="288"
202
+ y="140"
203
+ inkscape:label="64x64"/><rect
204
+ style="display:inline;overflow:visible;visibility:visible;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
205
+ id="rect96x96"
206
+ width="96"
207
+ height="96"
208
+ x="288"
209
+ y="28"
210
+ inkscape:label="96x96"/><rect
211
+ style="display:inline;overflow:visible;visibility:visible;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
212
+ id="rect256x256-7"
213
+ width="256"
214
+ height="256"
215
+ x="16"
216
+ y="28"
217
+ inkscape:label="256x256"/></g>
218
+ <g
219
+ inkscape:groupmode="layer"
220
+ id="layer4"
221
+ inkscape:label="Shadow"
222
+ style="display:inline"
223
+ sodipodi:insensitive="true"><rect
224
+ ry="50"
225
+ y="47"
226
+ x="34"
227
+ height="220"
228
+ width="220"
229
+ id="rect4114"
230
+ style="color:#bebebe;display:inline;overflow:visible;visibility:visible;opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;enable-background:accumulate" /></g>
231
+ <g
232
+ inkscape:groupmode="layer"
233
+ id="layer2"
234
+ inkscape:label="Background"
235
+ style="display:inline"><path
236
+ style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient4254);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
237
+ d="M 84,46.5 C 56.568735,46.5 34.5,68.568732 34.5,96 v 120 c 0,27.43127 22.068735,49.5 49.5,49.5 h 120 c 27.43127,0 49.5,-22.06873 49.5,-49.5 V 96 C 253.5,68.568732 231.43127,46.5 204,46.5 Z"
238
+ id="path4200" /></g>
239
+ <g
240
+ inkscape:groupmode="layer"
241
+ id="layer6"
242
+ inkscape:label="Symbols"
243
+ style="display:inline"><g
244
+ id="Layer_1-2"
245
+ data-name="Layer 1"
246
+ transform="matrix(1.322302,0,0,1.322302,59.921425,71.894979)"><path
247
+ class="cls-1"
248
+ d="M 18.45,63.47 A 18.4,18.4 0 0 0 2.31,45.23 73.13,73.13 0 0 0 2.31,81.7 18.38,18.38 0 0 0 18.45,63.47"
249
+ id="path1" /><path
250
+ class="cls-1"
251
+ d="M 29.13,57.7 A 5.77,5.77 0 1 0 34.9,63.47 5.77,5.77 0 0 0 29.13,57.7"
252
+ id="path2"/><path
253
+ class="cls-1"
254
+ d="m 108.72,63.47 a 18.38,18.38 0 0 0 16.14,18.23 73.13,73.13 0 0 0 0,-36.47 18.4,18.4 0 0 0 -16.14,18.24"
255
+ id="path3"/><path
256
+ class="cls-1"
257
+ d="m 98,57.7 a 5.77,5.77 0 1 0 5.76,5.77 A 5.77,5.77 0 0 0 98,57.7"
258
+ id="path4"/><path
259
+ class="cls-1"
260
+ d="m 63.46,108.77 a 18.39,18.39 0 0 0 -18.23,16.13 73.13,73.13 0 0 0 36.47,0 18.38,18.38 0 0 0 -18.24,-16.13"
261
+ id="path5"/><path
262
+ class="cls-1"
263
+ d="m 63.47,92.31 a 5.77,5.77 0 1 0 5.76,5.77 5.77,5.77 0 0 0 -5.76,-5.77"
264
+ id="path6"/><path
265
+ class="cls-1"
266
+ d="M 63.47,18.44 A 18.37,18.37 0 0 0 81.7,2.31 a 73.13,73.13 0 0 0 -36.47,0 18.39,18.39 0 0 0 18.24,16.13"
267
+ id="path7"/><path
268
+ class="cls-1"
269
+ d="m 63.47,23.37 a 5.77,5.77 0 1 0 5.76,5.76 5.76,5.76 0 0 0 -5.76,-5.76"
270
+ id="path8"/><path
271
+ class="cls-1"
272
+ d="m 95.44,95.44 a 18.4,18.4 0 0 0 -1.5,24.29 73,73 0 0 0 25.78,-25.79 18.39,18.39 0 0 0 -24.28,1.5"
273
+ id="path9"/><path
274
+ class="cls-1"
275
+ d="m 83.8,83.8 a 5.77,5.77 0 1 0 8.16,0 5.78,5.78 0 0 0 -8.16,0"
276
+ id="path10"/><path
277
+ class="cls-1"
278
+ d="M 31.59,31.59 A 18.36,18.36 0 0 0 33.09,7.31 72.93,72.93 0 0 0 7.31,33.09 18.36,18.36 0 0 0 31.59,31.59"
279
+ id="path11"/><path
280
+ class="cls-1"
281
+ d="m 35.07,35.08 a 5.77,5.77 0 1 0 8.16,0 5.78,5.78 0 0 0 -8.16,0"
282
+ id="path12"/><path
283
+ class="cls-1"
284
+ d="M 95.4,31.53 A 18.39,18.39 0 0 0 119.69,33 72.88,72.88 0 0 0 93.9,7.25 18.39,18.39 0 0 0 95.4,31.53"
285
+ id="path13"/><path
286
+ class="cls-1"
287
+ d="m 91.92,43.17 a 5.76,5.76 0 1 0 -8.15,0 5.76,5.76 0 0 0 8.15,0"
288
+ id="path14"/><path
289
+ class="cls-1"
290
+ d="M 31.56,95.37 A 18.39,18.39 0 0 0 7.28,93.87 73,73 0 0 0 33.06,119.66 18.38,18.38 0 0 0 31.56,95.37"
291
+ id="path15"/><path
292
+ class="cls-1"
293
+ d="m 35,83.73 a 5.77,5.77 0 1 0 8.16,0 5.79,5.79 0 0 0 -8.16,0"
294
+ id="path16"/></g></g>
295
+ <g
296
+ inkscape:groupmode="layer"
297
+ id="layer5"
298
+ inkscape:label="Highlights"
299
+ style="display:inline"
300
+ sodipodi:insensitive="true"><path
301
+ style="color:#bebebe;display:inline;overflow:visible;visibility:visible;opacity:0.13;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;enable-background:accumulate"
302
+ d="M 84,47 C 56.836703,47 35,68.836703 35,96 v 1 C 35,69.836703 56.836703,48 84,48 h 120 c 27.1633,0 49,21.836703 49,49 V 96 C 253,68.836703 231.1633,47 204,47 Z"
303
+ id="rect3894"
304
+ inkscape:connector-curvature="0" />
305
+ <path
306
+ id="path4085"
307
+ d="m 204,266 c 27.1633,0 49,-21.8367 49,-49 v -1 c 0,27.1633 -21.8367,49 -49,49 H 84 C 56.8367,265 35,243.1633 35,216 v 1 c 0,27.1633 21.8367,49 49,49 z"
308
+ style="color:#bebebe;display:inline;overflow:visible;visibility:visible;opacity:0.41;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;enable-background:accumulate"
309
+ inkscape:connector-curvature="0"/>
310
+ <path
311
+ inkscape:connector-curvature="0"
312
+ id="path4280"
313
+ d="M 84,265 C 56.836703,265 35,243.1633 35,216 v -1 c 0,27.1633 21.836703,49 49,49 h 120 c 27.1633,0 49,-21.8367 49,-49 v 1 c 0,27.1633 -21.8367,49 -49,49 z"
314
+ style="color:#bebebe;display:inline;overflow:visible;visibility:visible;opacity:0.1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;enable-background:accumulate"
315
+ inkscape:label="path4280"/></g>
316
+ <g
317
+ inkscape:groupmode="layer"
318
+ id="layer3"
319
+ inkscape:label="Border"
320
+ style="display:inline"
321
+ sodipodi:insensitive="true"><path
322
+ style="color:#bebebe;display:inline;overflow:visible;visibility:visible;opacity:0.41;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;enable-background:accumulate"
323
+ d="M 84,46 C 56.3,46 34,68.3 34,96 v 120 c 0,27.7 22.3,50 50,50 h 120 c 27.7,0 50,-22.3 50,-50 V 96 C 254,68.3 231.7,46 204,46 Z m 0,1 h 120 c 27.1633,0 49,21.836703 49,49 v 120 c 0,27.1633 -21.8367,49 -49,49 H 84 C 56.836703,265 35,243.1633 35,216 V 96 C 35,68.836703 56.836703,47 84,47 Z"
324
+ id="rect4040"
325
+ inkscape:connector-curvature="0" /></g></g></svg>
@@ -230,10 +230,13 @@ qt_resource_struct = b"\
230
230
  \x00\x00\x01\x8d\xcbE['\
231
231
  "
232
232
 
233
+
233
234
  def qInitResources():
234
235
  QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
235
236
 
237
+
236
238
  def qCleanupResources():
237
239
  QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
238
240
 
241
+
239
242
  qInitResources()
@@ -0,0 +1,2 @@
1
+ from .canvas_client import CanvasClient
2
+ from .legacy_canvas_types import LegacyFile, LegacyPage
@@ -99,7 +99,8 @@ class CanvasClient(SelfAuthenticating):
99
99
  async def get_page(self, page_id: str | int, course_id: str | int) -> LegacyPage:
100
100
  async with self._net_op_sem:
101
101
  response = detect_ratelimit_and_raise(
102
- await self.client.get(self.canvas_url.join(f"api/v1/courses/{course_id}/pages/{page_id}"), **self.get_headers()))
102
+ await self.client.get(self.canvas_url.join(f"api/v1/courses/{course_id}/pages/{page_id}"),
103
+ **self.get_headers()))
103
104
 
104
105
  return LegacyPage.from_dict(json.loads(response.text))
105
106
 
@@ -155,7 +156,8 @@ class CanvasClient(SelfAuthenticating):
155
156
  retries = 0
156
157
 
157
158
  while retries < self.max_retries:
158
- async with self.client.stream(method='GET', url=resource.url, cookies=self.client.cookies, follow_redirects=True) as resp:
159
+ async with self.client.stream(method='GET', url=resource.url, cookies=self.client.cookies,
160
+ follow_redirects=True) as resp:
159
161
  if await self.reauthenticate_if_needed(resp):
160
162
  retries += 1
161
163
  self._logger.warning("Retrying download of %s", resource.url)
@@ -1,6 +1,5 @@
1
1
  from typing import Any, TypeVar, Type, cast
2
2
 
3
-
4
3
  T = TypeVar("T")
5
4
 
6
5
 
@@ -66,7 +65,8 @@ class LegacyFile:
66
65
  hidden_for_user: bool
67
66
  locked_for_user: bool
68
67
 
69
- def __init__(self, id: int, uuid: str, display_name: str, filename: str, url: str, size: int, locked: bool, hidden: bool, hidden_for_user: bool, locked_for_user: bool) -> None:
68
+ def __init__(self, id: int, uuid: str, display_name: str, filename: str, url: str, size: int, locked: bool,
69
+ hidden: bool, hidden_for_user: bool, locked_for_user: bool) -> None:
70
70
  self.id = id
71
71
  self.uuid = uuid
72
72
  self.display_name = display_name
@@ -12,7 +12,8 @@ class CustomHTTPXAsyncTransport(HTTPXAsyncTransport):
12
12
  The transport uses the httpx library with anyio.
13
13
  """
14
14
 
15
- def __init__(self, client: httpx.AsyncClient, url: Union[str, httpx.URL], headers: dict[str, Any] | None = None, **kwargs):
15
+ def __init__(self, client: httpx.AsyncClient, url: Union[str, httpx.URL], headers: dict[str, Any] | None = None,
16
+ **kwargs):
16
17
  super().__init__(url=url, **kwargs)
17
18
  self.client = client
18
19
  self.headers = headers or {}
@@ -31,5 +32,3 @@ class CustomHTTPXAsyncTransport(HTTPXAsyncTransport):
31
32
  result["headers"] = self.headers
32
33
 
33
34
  return result
34
-
35
-
@@ -5,6 +5,7 @@ from asyncio import Lock, Event
5
5
  class AuthenticationException(Exception):
6
6
  pass
7
7
 
8
+
8
9
  # httpx does have an authentication flow mechanism that allows you to also make other requests but I don't know if it
9
10
  # will behave the same way as this does. I also finished this before I found out that existed.
10
11
 
@@ -1,7 +1,7 @@
1
1
  # qenerate: plugin=pydantic_v1
2
2
 
3
3
  query AllCourses($detailed: Boolean!) {
4
- allCourses {
5
- ...CanvasCourseData
6
- }
4
+ allCourses {
5
+ ...CanvasCourseData
6
+ }
7
7
  }
@@ -81,8 +81,8 @@ query AllCourses($detailed: Boolean!) {
81
81
 
82
82
  class ConfiguredBaseModel(BaseModel):
83
83
  class Config:
84
- smart_union=True
85
- extra=Extra.forbid
84
+ smart_union = True
85
+ extra = Extra.forbid
86
86
 
87
87
 
88
88
  class AllCoursesQueryData(ConfiguredBaseModel):
@@ -72,8 +72,8 @@ fragment CanvasCourseData on Course {
72
72
 
73
73
  class ConfiguredBaseModel(BaseModel):
74
74
  class Config:
75
- smart_union=True
76
- extra=Extra.forbid
75
+ smart_union = True
76
+ extra = Extra.forbid
77
77
 
78
78
 
79
79
  class Term(ConfiguredBaseModel):
@@ -10,12 +10,6 @@ class ContainerItem(QStandardItem):
10
10
  self.content = data
11
11
  self.setEditable(False)
12
12
 
13
-
14
13
  def data(self, role=257):
15
14
  if role == Qt.ItemDataRole.DisplayRole:
16
15
  return self.content.text
17
-
18
-
19
-
20
-
21
-