diff --git a/moodle_export/README.md b/moodle_export/README.md index 4c5d4cf..3b2ce35 100644 --- a/moodle_export/README.md +++ b/moodle_export/README.md @@ -8,17 +8,18 @@ Чтобы получить данные в файл csv следует прописать: -``` python3 grades_parser.py --moodle_token "your token" --url http://e.moevm.info --course_id "your course id"[,"id",..] --csv_path "name of file" [--percentages] [--options github]``` +``` python3 grades_parser.py --moodle_token "your token" --url http://e.moevm.info --course_id "your course id"[,"id",..] --csv_path "name of file" [--percentages] [--options github,sort]``` ``` Если хотите получить не баллы за задания, а проценты, то нужно добавить параметр ``` --percentages ```. Также в таблицу можно добавить опциональные графы по тегу ``` --options ``` без пробелов через запятую. -Пока из доступных есть опциональное поле ``` github ```. +Поле ``` github ``` добавляет графу github с пользовательским username. +Поле ``` sort ``` сортирует задания в порядке их расположения в курсе. Получение данных и в файл и в Google таблицу: -``` python3 grades_parser.py grades_parser --moodle_token "your token" --url http://e.moevm.info --course_id "your course id"[,"id",..] --csv_path "name of file" [--percentages] [--options github] --google_token "your google token" --table_id "your table id"[,"id",..] [--sheet_id "name of sheet"[,"name",..]] ``` +``` python3 grades_parser.py grades_parser --moodle_token "your token" --url http://e.moevm.info --course_id "your course id"[,"id",..] --csv_path "name of file" [--percentages] [--options github,sort] --google_token "your google token" --table_id "your table id"[,"id",..] [--sheet_id "name of sheet"[,"name",..]] ``` ``` Получение ``` .json ``` файла для google_token будет описано ниже. @@ -33,7 +34,7 @@ Запуск докер контейнера с параметрами: -``` docker run --rm grades_parser --moodle_token "your token" --url http://e.moevm.info --course_id "your course id"[,"id",..] --csv_path "name of file" [--percentages] [--options github] --google_token "your google token" --table_id "your table id"[,"id",..] [--sheet_id "name of sheet"[,"name",..]] ``` +``` docker run --rm grades_parser --moodle_token "your token" --url http://e.moevm.info --course_id "your course id"[,"id",..] --csv_path "name of file" [--percentages] [--options github,sort] --google_token "your google token" --table_id "your table id"[,"id",..] [--sheet_id "name of sheet"[,"name",..]] ``` ## Получение Moodle Токена. diff --git a/moodle_export/grades_parser.py b/moodle_export/grades_parser.py index 14ccdfd..a0736f5 100644 --- a/moodle_export/grades_parser.py +++ b/moodle_export/grades_parser.py @@ -1,24 +1,43 @@ #!/usr/bin/python3 +import re + import sheets import requests import json import datetime import csv import args_parser +from bs4 import BeautifulSoup HEADERS = { "Content-Type": "charset=iso-8859" } +def sort_id(cats, modules): + sorted_ids = [0] + for module in modules: + for i in range(len(cats)): + if module == cats[i]: + sorted_ids.append(i+1) + continue + return sorted_ids + +def sort_modules(acts, sorted_steps): + sorted_acts = [] + for i in sorted_steps: + sorted_acts.append(acts[i]) + return sorted_acts def main(): args = args_parser.arg_parser() for course_id in args.course_id: with requests.Session() as s: # get enrolled users + print('Get users data') res_users = s.get(args.url + '/webservice/rest/server.php?wstoken=' + args.moodle_token + '&wsfunction=core_enrol_get_enrolled_users&courseid=' + course_id + '&moodlewsrestformat=json', headers=HEADERS) + # check status code if res_users.status_code != 200: raise SystemExit("Request error, response status code: " + str(res_users.status_code)) @@ -29,6 +48,7 @@ def main(): raise SystemExit("Error: " + users["message"]) # save last accessed time for each user + print('Parse users data') users_params = {} for item in users: lastdate = datetime.datetime.fromtimestamp(item['lastcourseaccess']).strftime('%Y-%m-%d %H:%M:%S') @@ -40,6 +60,7 @@ def main(): users_params[str(item["id"])]["github"] = "-" # get grades + print('Get grades data') res_grades = s.get(args.url + '/webservice/rest/server.php?wstoken=' + args.moodle_token + '&wsfunction=gradereport_user_get_grades_table&courseid=' + course_id + '&moodlewsrestformat=json', headers=HEADERS) @@ -54,8 +75,37 @@ def main(): if "message" in grades: raise SystemExit("Error: " + grades["message"]) + # get modules + if args.options: + for i in args.options: + if i == 'sort': + print('Get modules') + course_content = s.get(args.url + '/webservice/rest/server.php?wstoken=' + args.moodle_token + + '&wsfunction=core_course_get_contents&courseid=' + course_id + '&moodlewsrestformat=json', + headers=HEADERS) + + # check status code + if course_content.status_code != 200: + raise SystemExit("Request error, response status code: " + str(course_content.status_code)) + + content = json.loads(course_content.text) + + # check if request is valid + if "message" in content: + raise SystemExit("Error: " + content["message"]) + + # get sorted modules + modules = [] + for topics in content: + for module in topics['modules']: + modules.append(str(module['id'])) + # parse needed grades data + print('Parse grades data') grades_data = [] + cats = [] + sorted_steps = [] + if_sorted = False for person in grades["tables"]: flag = '' person_grades = {} @@ -68,13 +118,12 @@ def main(): if i == 'github': person_grades["github"] = users_params[str(person_grades["userid"])]["github"] person_grades["userfullname"] = person["userfullname"] + person_grades_activities = [] person_grades["activities"] = [] - print("userid: " + str(person_grades["userid"]) + " fullname: " + person_grades["userfullname"]) for activities in person["tabledata"]: if type(activities) != list: activity = {} activity_name = activities["itemname"]["content"].partition("title=\"")[2].split("\" ")[0] - print(activity_name) activity_str1 = "activity " activity_str0 = "» " if activity_name == "Course total": @@ -90,13 +139,32 @@ def main(): activity["activity_name"] = activity_name[ activity_name.find(activity_str0) + len(activity_str0):] if flag != '': + if not if_sorted and args.options and activity["activity_name"] != "total": + for i in args.options: + if i == 'sort': + a = activities["itemname"]["content"].split('php?id=')[1] + cats.append(re.split(r'"|&', a)[0]) activity["grade"] = activities["grade"]["content"] activity["percentage"] = activities["percentage"]["content"] activity["contributiontocoursetotal"] = activities["contributiontocoursetotal"]["content"] - person_grades["activities"].append(activity) + person_grades_activities.append(activity) + if args.options: + for i in args.options: + if i == 'sort' and not if_sorted: + print('Sort modules') + sorted_steps = sort_id(cats, modules) + person_grades["activities"] = sort_modules(person_grades_activities, sorted_steps) + if_sorted = True + elif i == 'sort': + person_grades["activities"] = sort_modules(person_grades_activities, sorted_steps) + else: + person_grades["activities"] = person_grades_activities + else: + person_grades["activities"] = person_grades_activities grades_data.append(person_grades) # form suitable structure for output to sheets + print('Prepare data for publishing') grades_for_table = [] grades_type = "grade" if args.percentages: @@ -141,6 +209,7 @@ def main(): else: sheet_id = 'course ' + course_id + print('Data published! Check list: ' + sheet_id) sheets.write_data_to_table(csv_path, args.google_token, table_id, sheet_id)