NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Better Bb UBN course list // @version 2024-02-06 // @description Show all courses in year/semester groupings and ordered by title, for Bb UBN // @author asameshimae // @match https://online.manchester.ac.uk/ultra/course // @icon https://www.google.com/s2/favicons?sz=64&domain=manchester.ac.uk // @updateURL https://openuserjs.org/meta/asameshimae/Better_Bb_UBN_course_list.meta.js // @downloadURL https://openuserjs.org/install/asameshimae/Better_Bb_UBN_course_list.user.js // @grant none // @license MIT // ==/UserScript== /* jshint esversion: 8 */ async function init() { document.querySelector('#course-columns-current').textContent='' let sems = ['1SE','2SE','1YR'] let semHuman = sem=>['1st Semester','2nd Semester','Full Year'][sems.indexOf(sem)] let target = document.querySelector('#course-columns-current') let r = await fetch('https://online.manchester.ac.uk/learn/api/v1/users/me/memberships?limit=1000&expand=course.effectiveAvailability') let j = await r.json() let coursesYears = j.results.filter(e=>e.course.courseId.match(/\-1\d\d1\-(1SE|2SE|1YR)\-/)) let coursesFixed = j.results.filter(e=>!e.course.courseId.match(/\-1\d\d1\-(1SE|2SE|1YR)\-/)) let years = [...new Set(coursesYears.map(e=>e.course.courseId.split('-')[3]))].sort().reverse() let table = document.createElement('table') target.append(table) let tr = document.createElement('tr') tr.style.verticalAlign='top' table.append(tr) let td1 = document.createElement('td') tr.append(td1) years.forEach(yearCode=>{ let acYearStart2=(yearCode.substr(1,2)) let yearHuman=`20${acYearStart2}-${(+acYearStart2+1).toString().padStart(2,'0')}` let h2 = document.createElement('h2') h2.append(document.createTextNode(yearHuman)) td1.append(h2) let thisYearCourses = coursesYears.filter(e=>e.course.courseId.split('-')[3]===yearCode) for(let sem of sems) { let thisSemCourses = thisYearCourses.filter(e=>e.course.courseId.split('-')[4]===sem) if(thisSemCourses.length) { let thisSemCourseNames = thisSemCourses.map(e=>e.course.displayName).sort() let h3 = document.createElement('h3') h3.append(document.createTextNode(semHuman(sem))) td1.append(h3) let ul = document.createElement('ul') thisSemCourseNames.forEach(name=>{ let thisCourseUrl = thisSemCourses.find(e=>e.course.displayName===name).course.externalAccessUrl let li = document.createElement('li') let a = document.createElement('a') a.append(document.createTextNode(name)) a.href = thisCourseUrl li.append(a) ul.append(li) }) td1.append(ul) } } }) let td2 = document.createElement('td') td2.style.paddingLeft='1em' tr.append(td2) let h2 = document.createElement('h2') h2.append(document.createTextNode('Organisations')) td2.append(h2) let ul = document.createElement('ul') let orgCourseNames = coursesFixed.map(e=>e.course.displayName).sort() orgCourseNames.forEach(name=>{ let thisCourseUrl = coursesFixed.find(e=>e.course.displayName===name).course.externalAccessUrl let li = document.createElement('li') let a = document.createElement('a') a.append(document.createTextNode(name)) a.href = thisCourseUrl li.append(a) ul.append(li) }) td2.append(ul) } var i (function(){ i = setInterval(()=>{ let test = document.querySelector('#course-columns-current') if(test) { clearInterval(i) init() } },500) })()