From d97cb7950b3765d3c748da6ec477eb68dd2b7a87 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Sat, 17 Oct 2020 02:42:11 +0200 Subject: Refractor gui.MoodleFetcher --- gui.py | 110 ++++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/gui.py b/gui.py index 6b20d72..bdb3868 100644 --- a/gui.py +++ b/gui.py @@ -11,7 +11,7 @@ import logging from PyQt5.QtGui import QFont from PyQt5.Qt import QStyle -from PyQt5.QtCore import Qt, QThread, pyqtSlot +from PyQt5.QtCore import Qt, QThread, pyqtSlot, pyqtSignal from PyQt5.QtWidgets import QApplication, QWidget, QTreeWidget, QTreeWidgetItem, QTreeWidgetItemIterator, QGridLayout, QHBoxLayout, QPushButton, QProgressBar, QTabWidget, QPlainTextEdit import moodle @@ -27,6 +27,7 @@ class MoodleItem(QTreeWidgetItem): SECTION = 2 # modules MODULE = 3 + ## specific module types FORUM = 4 RESOURCE = 5 FOLDER = 6 @@ -35,6 +36,7 @@ class MoodleItem(QTreeWidgetItem): QUIZ = 9 # contents CONTENT = 10 + ## specific content types FILE = 11 URL = 12 @@ -74,68 +76,71 @@ class MoodleItem(QTreeWidgetItem): self.setText(0, html.unescape(self.metadata.title)) class MoodleFetcher(QThread): + loadedItem = pyqtSignal(MoodleItem.Type, object) + def __init__(self, parent, instance_url, token): super().__init__() self.api = moodle.RestApi(instance_url, token) self.apihelper = moodle.ApiHelper(self.api) - self.moodleItems = MoodleItem(MoodleItem.Type.ROOT, title="ROOT") def run(self): # This is beyond bad but I don't have access to the moodle documentation, so I had to guess - courses = self.api.core_enrol_get_users_courses(userid=self.apihelper.get_userid()).json() - for course in courses: - courseItem = MoodleItem(MoodleItem.Type.COURSE, - id = course["id"], title = course["shortname"]) - - self.moodleItems.addChild(courseItem) - - sections = self.api.core_course_get_contents(courseid=courseItem.metadata.id).json() - - for section in sections: - sectionItem = MoodleItem(MoodleItem.Type.SECTION, - id = section["id"], title = section["name"]) - - courseItem.addChild(sectionItem) - - modules = section["modules"] if "modules" in section else [] - for module in modules: - moduleType = { - "folder" : MoodleItem.Type.FOLDER, - "resource" : MoodleItem.Type.RESOURCE, - "forum" : MoodleItem.Type.FORUM, - "attendance" : MoodleItem.Type.ATTENDANCE, - "label" : MoodleItem.Type.LABEL, - "quiz" : MoodleItem.Type.QUIZ, - } - - moduleItem = MoodleItem(moduleType.get(module["modname"]) or MoodleItem.Type.MODULE, - id = module["id"], title = module["name"]) - - sectionItem.addChild(moduleItem) - - contents = module["contents"] if "contents" in module else [] - for content in contents: - contentType = { - "url" : MoodleItem.Type.URL, - "file" : MoodleItem.Type.FILE, - } - - contentItem = MoodleItem(contentType.get(content["type"]) or MoodleItem.Type.MODULE, - title = content["filename"], url = content["fileurl"]) - - moduleItem.addChild(contentItem) - + for course in self.getCourses(): + self.loadedItem.emit(MoodleItem.Type.COURSE, course) + for section in self.getSections(course): + self.loadedItem.emit(MoodleItem.Type.SECTION, section) + for module in self.getModules(section): + self.loadedItem.emit(MoodleItem.Type.MODULE, module) + for content in self.getContent(module): + self.loadedItem.emit(MoodleItem.Type.CONTENT, content) + + def getCourses(self): + courses = self.api.core_enrol_get_users_courses(userid = self.apihelper.get_userid()).json() + if "exception" in courses: + log.error("failed to load courses") + log.debug(courses) + return [] + else: + return courses + + def getSections(self, course): + if not "id" in course: + log.error("cannot get sections from invalid course") + log.debug(course) + return [] + else: + sections = self.api.core_get_contents(courseid = str(course["id"])).json() + if "exception" in sections: + log.error(f"failed to load sections from course with id {course['id']} ({course['shortname']})") + log.debug(sections) + return [] + else: + return sections + + def getModules(self, section): + if "modules" in section: + return section["modules"] + else: + return [] + + def getContent(self, module): + if "contents" in module: + return module["contents"] + else: + return [] class MoodleTreeView(QTreeWidget): def __init__(self, parent, instance_url, token): super().__init__(parent) + self.initUi() + self.worker = MoodleFetcher(self, instance_url, token) + self.worker.loadedItem.connect(self.onWorkerLoadedItem) self.worker.finished.connect(self.onWorkerDone) self.worker.start() - self.initUi() self.show() def initUi(self): @@ -148,21 +153,22 @@ class MoodleTreeView(QTreeWidget): if item.type == MoodleItem.Type.FILE: pass + # @pyqtSlot() + def onWorkerLoadedItem(self, type, item): + log.debug(f"loaded item of type {type}") + @pyqtSlot() def onWorkerDone(self): - log.debug("worker done") - for item in QTreeWidgetItemIterator(self.worker.moodleItems): - self.addTopLevelItem(item) - - # sort only after the worker is done for efficiency self.setSortingEnabled(True) class QPlainTextEditLogger(logging.Handler): def __init__(self, parent): super().__init__() - # TODO: set monospaced font + font = QFont("Monospace") + font.setStyleHint(QFont.Monospace) self.widget = QPlainTextEdit(parent) self.widget.setReadOnly(True) + self.widget.setFont(font) def emit(self, record): msg = self.format(record) -- cgit v1.2.1