var courses; // get the courses from storage setCourseList(); // var modhtml = ''; // $("#html").prepend(modhtml); getSemesters(); var canremove = true; function setCourseList() { $("#courseList").empty() chrome.storage.sync.get('savedCourses', function (data) { updateConflicts(); courses = data.savedCourses console.log(courses.length); if (courses.length != 0) { $("#empty").hide(); $("#courseList").show(); } else { showEmpty(); } // build and append the course list element for (var i = 0; i < courses.length; i++) { var color; var subcolor; status = courses[i].status; if (status.includes("open")) { color = "#4CAF50"; subcolor = "#C8E6C9"; } else if (status.includes("waitlisted")) { color = "#FF9800" subcolor = "#FFE0B2"; } else if (status.includes("closed") || status.includes("cancelled")) { color = "#FF5722"; subcolor = "#FFCCBC"; } var department = courses[i].coursename.substring(0, courses[i].coursename.search(/\d/) - 2); var course_nbr = courses[i].coursename.substring(courses[i].coursename.search(/\d/), courses[i].coursename.indexOf(" ", courses[i].coursename.search(/\d/))); var profname = prettifyName(courses[i].profname); if (profname == "") { profname = "Undecided Professor"; } var listhtml = `
  • ${department} ${course_nbr} with ${profname} (${courses[i].unique})

  • `; $("#courseList").append(listhtml); } }); } function showEmpty() { var emptyText = ["Doesn't Look Like Anything To Me.", "You Can't Fail Classes You're Not In.", "Pro-Tip: Don't Take O-Chem.", "No Work Happens On PCL 5th Floor.", "Sophomore But Freshman By Credit.", "Pain is temporary, GPA is forever.", "You've Yee'd Your Last Haw.", "lol everything is already waitlisted.", "At Least You're Not At A&M.", `It's ${moment().format("h:mm")} and OU Still Sucks.`, 'TeXAs iS BaCK GuYZ', "'Academically Challenged'", 'Does McCombs teach Parseltongue?', 'Lets make Daddy Fenves proud.', 'Feel bad if you say Wampus.', 'No Cruce Enfrente Del Bus.', 'Midterm 1 has been Unmuted', 'Omae Wa Mou Shindeiru...', 'Bevo Bucks are the new Bitcoin' ] // console.log(emptyText.length); $("#courseList").hide(); $("#empty").fadeIn(200); $("#main").html(emptyText[Math.floor(Math.random() * emptyText.length)]); } /* prettify the name for the conflict messages*/ function getSimpleName(coursename, unique) { var department = coursename.substring(0, coursename.search(/\d/) - 2); var course_nbr = coursename.substring(coursename.search(/\d/), coursename.indexOf(" ", coursename.search(/\d/))); return department + " " + course_nbr + " (" + unique + ")"; } /* Format the Professor Name */ function prettifyName(profname) { return profname.replace(/\w\S*/g, function (txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); }); } /* Update the conflict messages */ function updateConflicts() { chrome.runtime.sendMessage({ command: "checkConflicts" }, function (response) { var isConflicted = []; if (response.isConflict) { var between = response.between; var text = ""; for (var i = 0; i < between.length; i++) { text += "CONFLICT: " + getSimpleName(between[i][0].coursename, between[i][0].unique) + " and " + getSimpleName(between[i][1].coursename, between[i][1].unique); isConflicted.push(between[i][0].unique); isConflicted.push(between[i][1].unique); if (i != between.length - 1) { text += "
    "; } } $("

    " + text + "").prependTo("#courseList").hide().fadeIn(200); } }); } /* Handle the button clicks */ $(document).ready(function () { $("#courseList").on('mouseover', '.copybut', function () { $(this).addClass('shadow'); }).on('mouseleave', '.copybut', function () { $(this).removeClass('shadow'); }); $("#courseList").on('click', '.copybut', function (e) { e.stopPropagation(); var temp = $(""); $(this).find('i').text('check'); $(this).stop(true, false).removeAttr('style').removeClass('shadow', { duration: 200 }); $(this).find('i').delay(400).queue(function (n) { $(this).text('content_copy'); $(this).parent().removeClass('shadow'); if ($(this).parent().is(":hover")) { $(this).parent().addClass('shadow'); } n(); }) $("body").append(temp); temp.val($(this).val()).select(); document.execCommand("copy"); temp.remove(); }); $("#courseList").on('click', 'li', function () { $(this).find("#listMoreInfo").click(function () { window.open(courses[$(this).closest("li").attr("id")].link); }); let status = courses[$(this).closest("li").attr("id")].status; let registerlink = courses[$(this).closest("li").attr("id")].registerlink; if (status.includes("closed") || status.includes("cancelled") || !status || !registerlink) { $(this).find("#register").text("Can't Register").css("background-color", "#FF5722"); } else { if (status.includes("waitlisted")) { $(this).find("#register").text("Join Waitlist").css("background-color", "#FF9800"); } else { $(this).find("#register").text("Register").css("background-color", "#4CAF50"); } $(this).find("#register").click(function () { chrome.tabs.query({ currentWindow: true, active: true }, function (tab) { chrome.tabs.update(tab.id, { url: registerlink }); }); }) } /* clear the conflict messages, then remove the course and updateConflicts. update the tabs*/ $(this).find("#listRemove").click(function () { var thisForm = this; if (canremove) { canremove = false; $(thisForm).closest("ul").find("#conflict").fadeOut(300, function () { $(this).remove(); }); chrome.runtime.sendMessage({ command: "courseStorage", course: courses[$(thisForm).closest("li").attr("id")], action: "remove" }, function (response) { $(thisForm).closest("li").fadeOut(200); if ($(thisForm).closest("ul").children(':visible').length === 1) { showEmpty(); } canremove = true; console.log('computedconflicts'); updateConflicts(); chrome.tabs.query({}, function (tabs) { for (var i = 0; i < tabs.length; i++) { chrome.tabs.sendMessage(tabs[i].id, { command: "updateCourseList" }); } }); }); } }); /* Show the times popout and more info options*/ if ($(this).find("#moreInfo").is(":hidden")) { $(this).find("#moreInfo").fadeIn(200); $(this).find('#arrow').css('transform', 'rotate(90deg)'); } else { $(this).find("#moreInfo").fadeOut(200); $(this).find('#arrow').css('transform', ''); } }); $("#clear").click(function () { clear(); }); $("#schedule").click(function () { chrome.tabs.create({ 'url': 'https://registrar.utexas.edu/schedules' }); }); $("#impexp").click(function () { if ($("#impexp>i").text() == 'close') { $('#import').hide(); $('#export').hide(); $("#impexp>i").text('import_export'); // $(this).removeClass('selected'); } else { $("#impexp>i").text('close'); $('#import').show(); // $(this).addClass('selected'); $('#export').show(); } }); $("#search").click(function () { if ($("#search>i").text() == 'close') { $("#search>i").text('search'); $("#class_id_input").hide(); $("#semcon").hide(); $("#semesters").hide(); $("#search-popup").addClass('hide'); // $(this).removeClass('selected'); } else { $("#search>i").text('close'); $("#class_id_input").show(); $("#semesters").show(); $("#semcon").show(); $('#class_id_input').focus(); $("#search-popup").removeClass('hide'); // $(this).addClass('selected'); } }); $('#import').click(function () { $("#importOrig").click(); }); $('#export').click(function () { chrome.storage.sync.get('savedCourses', function (data) { if (data.savedCourses.length > 0) { var exportlink = document.createElement('a'); var url = window.URL.createObjectURL(new Blob([JSON.stringify(data.savedCourses, null, 4)], { type: "octet/stream" })); exportlink.setAttribute('href', url); exportlink.setAttribute('download', 'my_courses.json'); exportlink.click(); } else { alert('No Saved Courses to Export.'); } }); }); $("#search-class").click(() => { var uniqueId = $("#class_id_input").val(); if (!isNaN(uniqueId)) { if (uniqueId.length == 5) { let selectedSemester = $("#semesters").find(":selected").val(); openCoursePage(selectedSemester, uniqueId); $("#class_id_input").val(''); return; } } alert("Oops, check your input. Class IDs should have 5 digits!"); }); $("#open").click(function () { chrome.tabs.create({ 'url': "options.html" }); }); $("#calendar").click(function () { chrome.tabs.create({ 'url': "calendar.html" }); }); }); $("#importOrig").change(function (e) { var files = e.target.files; var reader = new FileReader(); reader.onload = function () { try { var impCourses = JSON.parse(this.result); console.log(impCourses); if (impCourses && impCourses.length && (impCourses.length == 0 || validateObject(impCourses))) { chrome.storage.sync.set({ savedCourses: impCourses }); chrome.runtime.sendMessage({ command: "updateBadge" }); chrome.tabs.query({}, function (tabs) { for (var i = 0; i < tabs.length; i++) { chrome.tabs.sendMessage(tabs[i].id, { command: "updateCourseList" }); } }); setCourseList(); chrome.runtime.sendMessage({ command: "updateStatus", }); } } catch (err) { } importOrig.value = ''; } reader.readAsText(files[0]); }); function validateObject(impCourses) { for (var i = 0; i < impCourses.length; i++) { var course = impCourses[i]; var isValid = true; var props = ["coursename", "datetimearr", "link", "profname", "status", "unique"]; console.log(course.coursename); for (let j = 0; j < props.length; j++) { isValid &= course.hasOwnProperty(props[j]); } console.log(isValid); if (!isValid) { return false; } } return true; } /* convert from the dtarr and maek the time lines*/ function makeLine(index) { var datetimearr = courses[index].datetimearr; //converted times back var dtmap = new Map([]); for (var i = 0; i < datetimearr.length; i++) { datetimearr[i][1][0] = moment(datetimearr[i][1][0], ["HH:mm"]).format("h:mm a"); datetimearr[i][1][1] = moment(datetimearr[i][1][1], ["HH:mm"]).format("h:mm a"); } for (var i = 0; i < datetimearr.length; i++) { if (dtmap.has(String(datetimearr[i][1]))) { dtmap.set(String(datetimearr[i][1]), dtmap.get(String(datetimearr[i][1])) + datetimearr[i][0]); } else { dtmap.set(String(datetimearr[i][1]), datetimearr[i][0]); } } var output = ""; var timearr = Array.from(dtmap.keys()); var dayarr = Array.from(dtmap.values()); if (timearr.length == 0) { output = "This class has no meeting times." } else { for (var i = 0; i < dayarr.length; i++) { var place = findLoc(dayarr[i], timearr[i], datetimearr); var building = place.substring(0, place.search(/\d/) - 1); if (building == "") { building = "Undecided Location"; } output += `${dayarr[i]}:${timearr[i].split(",")[0]} to ${timearr[i].split(",")[1]}${place}
    `; } } return output; } //find the location of a class given its days and timearrs. function findLoc(day, timearr, datetimearr) { for (let i = 0; i < datetimearr.length; i++) { var dtl = datetimearr[i]; // console.log(dtl[1]); // console.log(timearr); if (day.includes(dtl[0])) { if (JSON.stringify(timearr) == JSON.stringify(fixDtl1(dtl[1]))) { return dtl[2]; } } } } function fixDtl1(dtl1) { let output = ""; for (let i = 0; i < dtl1.length; i++) { output += dtl1[i]; if (i != dtl1.length - 1) { output += ","; } } return output; } /*Clear the list and the storage of courses*/ function clear() { chrome.storage.sync.set({ savedCourses: [] }); chrome.tabs.query({}, function (tabs) { for (var i = 0; i < tabs.length; i++) { chrome.tabs.sendMessage(tabs[i].id, { command: "updateCourseList" }); } }); chrome.runtime.sendMessage({ command: "updateBadge" }); $("#courseList").empty() console.log("cleared"); showEmpty(); } function getSemesters() { var schedulelist = 'https://registrar.utexas.edu/schedules'; $.get(schedulelist, function (response) { if (response) { var object = $('

    ').html(response).contents(); object.find('.callout2>ul>li>a').each(function (index) { if (index < 2) { if ($(this).text() != "Course Schedule Archive") { const semester = $(this).text().split(" ")[0]; const year = $(this).text().split(" ")[1] let semname = semester + " " + year; console.log('semname:::: ' + semname); $("#semesters").append(``); $.get($(this).attr('href'), function (response) { if (response) { var object = $('
    ').html(response).contents(); // Check title of page and see if it matches semester name var name = object.find(".page-title").text(); name = name.substring(name.lastIndexOf('|') + 1).trim(); name = name.split(" ")[0] + " " + name.split(" ")[1]; console.log('name:::: ' + name); object.find('.gobutton>a').each(function () { var semnum = $(this).attr('href').substring($(this).attr('href').lastIndexOf('/') + 1); console.log('semnum:::: ' + semnum); $("option").each(function () { console.log($(this).text()); if ($(this).text() == name) { $(this).val(semnum); console.log($(this).val()); } }) }); } }); } } }); } }); } /*Course object for passing to background*/ function Course(coursename, unique, profname, datetimearr, status, link, registerlink) { this.coursename = coursename; this.unique = unique; this.profname = profname; this.datetimearr = datetimearr; this.status = status; this.link = link; this.registerlink = registerlink; } function openCoursePage(sem, unique) { var link = `https://utdirect.utexas.edu/apps/registrar/course_schedule/${sem}/${unique}/`; window.open(link); } /*For a row, get all the course information and add the date-time-lines*/ function getCourseObject(object, link) { let coursename = object.find("#details h2").text(); let uniquenum = object.find('td[data-th="Unique"]').text(); let profname = object.find("td[data-th='Instructor']").text().split(', ')[0]; if (profname.indexOf(" ") == 0) { profname = profname.substring(1); } let datetimearr = getDtarr(object); let status = object.find('td[data-th="Status"]').text(); let indlink = link; let registerlink = object.find('td[data-th="Add"] a').prop('href'); return new Course(coursename, uniquenum, profname, datetimearr, status, indlink, registerlink); } /* For a row, get the date-time-array for checking conflicts*/ function getDtarr(object) { var numlines = object.find('td[data-th="Days"]>span').length; var dtarr = []; for (var i = 0; i < numlines; i++) { var date = object.find('td[data-th="Days"]>span:eq(' + i + ')').text(); var time = object.find('td[data-th="Hour"]>span:eq(' + i + ')').text(); var place = object.find('td[data-th="Room"]>span:eq(' + i + ')').text(); for (var j = 0; j < date.length; j++) { var letter = date.charAt(j); var day = ""; if (letter == "T" && j < date.length - 1 && date.charAt(j + 1) == "H") { dtarr.push(["TH", convertTime(time), place]); } else { if (letter != "H") { dtarr.push([letter, convertTime(time), place]); } } } } return dtarr; } /*Convert time to 24hour format*/ function convertTime(time) { var converted = time.replace(/\./g, '').split("-"); for (var i = 0; i < 2; i++) { converted[i] = moment(converted[i], ["h:mm A"]).format("HH:mm"); } return converted; }