2023-05-01 20:20:12 +02:00
|
|
|
import re
|
|
|
|
|
2023-05-01 01:12:48 +02:00
|
|
|
import requests
|
|
|
|
|
2023-05-08 15:25:13 +02:00
|
|
|
|
2023-05-01 01:12:48 +02:00
|
|
|
# a minimalistic moodle api wrapper, just for the purpose of this project
|
|
|
|
# it's not meant to be complete
|
|
|
|
# it's not meant to be efficient
|
|
|
|
# it's not meant to be pythonic
|
|
|
|
# it's not meant to be a good moodle api wrapper
|
|
|
|
|
|
|
|
|
|
|
|
class Category:
|
|
|
|
def __init__(self, id_i: int, name: str, courses: list):
|
|
|
|
self.id = id_i
|
|
|
|
self.name = name
|
|
|
|
self.courses = courses
|
|
|
|
|
|
|
|
|
|
|
|
class Course:
|
|
|
|
def __init__(self, id_i: int, shortname: str, fullname: str, enrolled_user_count: int):
|
|
|
|
self.shortname = shortname
|
|
|
|
self.fullname = fullname
|
|
|
|
self.id = id_i
|
|
|
|
self.enrolled_user_count = enrolled_user_count
|
|
|
|
|
|
|
|
|
|
|
|
class Section:
|
|
|
|
def __init__(self, id_i: int, name: str, htmlcontent: str, modules: list):
|
|
|
|
self.id = id_i
|
2023-05-01 20:20:12 +02:00
|
|
|
self.autoName = False
|
|
|
|
if len(re.sub(r'\W+', '', name)) == 0:
|
2023-05-01 01:12:48 +02:00
|
|
|
name = "Section " + str(id_i)
|
2023-05-01 20:20:12 +02:00
|
|
|
self.autoName = True
|
2023-05-01 01:12:48 +02:00
|
|
|
self.name = name
|
|
|
|
self.htmlcontent = htmlcontent
|
|
|
|
self.modules = modules
|
|
|
|
|
|
|
|
|
|
|
|
class Label:
|
|
|
|
def __init__(self, id_i: int, htmlcontent: str):
|
|
|
|
self.id = id_i
|
|
|
|
self.htmlcontent = htmlcontent
|
|
|
|
self.name = "Label" + str(id_i)
|
|
|
|
|
|
|
|
|
|
|
|
class Url:
|
|
|
|
def __init__(self, id_i: int, name: str, description: str, url: str):
|
|
|
|
self.id = id_i
|
|
|
|
self.name = name
|
|
|
|
self.description = description
|
|
|
|
self.url = url
|
|
|
|
|
|
|
|
|
|
|
|
class MoodleUser:
|
|
|
|
def __init__(self, username: str, fullname: str, user_picture_url: str):
|
|
|
|
self.username = username
|
|
|
|
self.fullname = fullname
|
|
|
|
self.user_picture_url = user_picture_url
|
|
|
|
|
|
|
|
|
|
|
|
class Folder:
|
|
|
|
def __init__(self, id_i: int, name: str, files: list):
|
|
|
|
self.id = id_i
|
|
|
|
self.name = name
|
|
|
|
self.files = files
|
|
|
|
|
|
|
|
|
|
|
|
class File:
|
2023-05-08 15:25:13 +02:00
|
|
|
def __init__(self, filename: str, filesize: int, fileurl: str, file_relative_path: str | None, created: int | None,
|
|
|
|
modified: int | None):
|
2023-05-01 01:12:48 +02:00
|
|
|
self.filename = filename
|
|
|
|
self.name = filename
|
|
|
|
self.filesize = filesize
|
|
|
|
self.fileurl = fileurl
|
2023-05-08 15:25:13 +02:00
|
|
|
self.file_relative_path = file_relative_path
|
|
|
|
self.created = created
|
|
|
|
self.modified = modified
|
2023-05-01 01:12:48 +02:00
|
|
|
|
|
|
|
|
|
|
|
class Moodle:
|
|
|
|
def __init__(self, site_url, username, password):
|
|
|
|
self.user_id = None
|
|
|
|
self.token = None
|
|
|
|
self.private_token = None
|
|
|
|
self.site_url = site_url
|
|
|
|
self.username = username
|
|
|
|
self.password = password
|
2023-05-09 09:53:54 +02:00
|
|
|
self.site_name = None
|
|
|
|
self.release = None
|
|
|
|
self.lang = None
|
2023-05-01 01:12:48 +02:00
|
|
|
|
|
|
|
def login(self) -> None:
|
|
|
|
url = self.site_url + "/login/token.php?username=" + self.username + "&password=" + self.password + "&service=moodle_mobile_app"
|
|
|
|
response = requests.post(url)
|
|
|
|
r = response.json()
|
|
|
|
if "error" in r.keys():
|
|
|
|
raise Exception(r["error"])
|
|
|
|
self.token = r["token"]
|
|
|
|
self.private_token = r["privatetoken"]
|
2023-05-01 20:20:12 +02:00
|
|
|
self.get_user()
|
2023-05-01 01:12:48 +02:00
|
|
|
|
|
|
|
def get_user(self) -> MoodleUser:
|
|
|
|
url = self.site_url + "/webservice/rest/server.php?moodlewsrestformat=json"
|
|
|
|
re = requests.post(url, data={"wstoken": self.token, "wsfunction": "core_webservice_get_site_info"})
|
|
|
|
r = re.json()
|
|
|
|
self.user_id = r["userid"]
|
|
|
|
self.userpictureurl = r["userpictureurl"]
|
|
|
|
self.fullname = r["fullname"]
|
2023-05-09 09:53:54 +02:00
|
|
|
self.site_name = r["sitename"]
|
|
|
|
self.release = r["release"]
|
|
|
|
self.lang = r["lang"]
|
2023-05-01 01:12:48 +02:00
|
|
|
return MoodleUser(self.username, self.fullname, self.userpictureurl)
|
|
|
|
|
|
|
|
def get_enrolled_categories(self) -> list[Category]:
|
|
|
|
url = self.site_url + "/webservice/rest/server.php?moodlewsrestformat=json"
|
|
|
|
re = requests.post(url, data={"wstoken": self.token, "wsfunction": "core_enrol_get_users_courses",
|
|
|
|
"userid": self.user_id})
|
|
|
|
r = re.json()
|
|
|
|
categories = {}
|
|
|
|
for course in r:
|
|
|
|
if course["category"] not in categories.keys():
|
|
|
|
categories[course["category"]] = []
|
|
|
|
categories[course["category"]].append(
|
|
|
|
Course(course["id"], course["shortname"], course["fullname"], course["enrolledusercount"]))
|
|
|
|
lret = []
|
|
|
|
for category_id in categories.keys():
|
|
|
|
c = self.get_category_by_id(category_id)
|
|
|
|
c.courses = categories[category_id]
|
|
|
|
lret.append(c)
|
|
|
|
return lret
|
|
|
|
|
|
|
|
def get_enrolled_courses(self) -> Category:
|
|
|
|
url = self.site_url + "/webservice/rest/server.php?moodlewsrestformat=json"
|
|
|
|
re = requests.post(url, data={"wstoken": self.token, "wsfunction": "core_enrol_get_users_courses",
|
|
|
|
"userid": self.user_id})
|
|
|
|
return re.json()
|
|
|
|
|
|
|
|
def get_category_by_id(self, category_id: int) -> Category:
|
|
|
|
url = self.site_url + "/webservice/rest/server.php?moodlewsrestformat=json"
|
|
|
|
re = requests.post(url, data={"wstoken": self.token, "wsfunction": "core_course_get_categories",
|
|
|
|
"criteria[0][key]": "id", "criteria[0][value]": category_id})
|
|
|
|
r = re.json()
|
|
|
|
return Category(r[0]["id"], r[0]["name"], [])
|
|
|
|
|
|
|
|
def get_course_content(self, course_id: int) -> list[Section]:
|
|
|
|
url = self.site_url + "/webservice/rest/server.php?moodlewsrestformat=json"
|
|
|
|
re = requests.post(url, data={"wstoken": self.token, "wsfunction": "core_course_get_contents",
|
|
|
|
"courseid": course_id})
|
|
|
|
r = re.json()
|
|
|
|
sections = []
|
|
|
|
for section in r:
|
|
|
|
modules = []
|
|
|
|
for module in section["modules"]:
|
|
|
|
if module["modname"] == "label":
|
|
|
|
modules.append(Label(module["id"], module["description"]))
|
|
|
|
elif module["modname"] == "url":
|
|
|
|
modules.append(Url(module["id"], module["name"],
|
|
|
|
(module["description"] if "description" in module.keys() else ""),
|
|
|
|
module["url"]))
|
2023-05-08 15:25:13 +02:00
|
|
|
elif module["modname"] == "folder" or module["modname"] == "resource":
|
2023-05-01 01:12:48 +02:00
|
|
|
modules.append(self.__folder_rec_exploder(module))
|
|
|
|
elif module["modname"] == "file":
|
2023-05-08 15:25:13 +02:00
|
|
|
modules.append(File(module["filename"], module["filesize"], module["fileurl"], module["filepath"], module["timecreated"], module["timemodified"]))
|
2023-05-01 01:12:48 +02:00
|
|
|
|
|
|
|
sections.append(Section(section["id"], section["name"], section["summary"], modules))
|
|
|
|
return sections
|
|
|
|
|
|
|
|
def __folder_rec_exploder(self, folder_module: dict) -> Folder:
|
|
|
|
f = Folder(folder_module["id"], folder_module["name"], [])
|
|
|
|
for file in folder_module["contents"]:
|
|
|
|
if file["type"] == "file":
|
2023-05-08 15:25:13 +02:00
|
|
|
f.files.append(File(file["filename"], file["filesize"], file["fileurl"], file["filepath"], file["timecreated"], file["timemodified"]))
|
2023-05-01 01:12:48 +02:00
|
|
|
else:
|
|
|
|
f.files.append(self.__folder_rec_exploder(file))
|
|
|
|
return f
|