CCAU - Modules Section

Automate course copies

// ==UserScript==
// @name        CCAU - Modules Section
// @namespace   CCAU Suite
// @description Automate course copies
// @match       https://*.instructure.com/courses/*/modules
// @version     1.0.4
// @author      miruqi
// @icon        https://du11hjcvx0uqb.cloudfront.net/br/dist/images/favicon-e10d657a73.ico
// @grant       none
// @license     GPL-3.-or-later
// ==/UserScript==
(()=>{function f(e,t,n){let c=document.querySelector(n),o=document.createElement("a");o.textContent=e,o.classList.add("btn"),o.setAttribute("tabindex","0"),o.addEventListener("click",t,!1),c?.insertAdjacentElement("afterbegin",o),c?.insertAdjacentHTML("afterbegin","&nbsp;")}function b(e){document.querySelector(e)?.click()}function u(e,t){let n=e;return t.forEach(c=>{let o=n?.children,r=o.length,s=c>=0?c:r+c;r>s&&(n=o[s])}),n}function p(e,t=0){return i().findIndex((n,c)=>c>=t&&n.title.toLowerCase()===e.toLowerCase())}function a(e){console.log("[CCAU] "+e)}function i(){let e=".collapse_module_link";return Array.from(document.querySelectorAll(e))}function g(e,t){let c=i()[e].parentElement;u(c,[5,0,t])?.click()}function y(){let e=window.confirm;return window.confirm=()=>!0,e}function x(e){window.confirm=e}function _(e,t){let n=document.querySelectorAll(".ig-row"),c=n.length;for(let o=0;o<c;o++){let r=n[o],s=u(r,[2,0]),h=u(r,e),m=s?.innerText||"";/^\*?[a-z]{3,12} \d{1,2} - [a-z]{0,12} ?\d{1,2}\*?$/.test(m.toLowerCase())&&(h?.click(),t(m))}}function D(e){a(`Removing date header: ${e}`);let t=document.querySelectorAll(".ui-kyle-menu"),n=Array.from(t).map(o=>o),c=n.length;for(let o=0;o<c;o++){if(n[o].getAttribute("aria-hidden")!=="false")continue;let r=n[o].children.length;u(n[o],[r-1,0])?.click()}}function k(){let e=y();_([3,2,1,-1,0],D),x(e)}var A="https://raw.githubusercontent.com/Abendsonnenschein/CCAU-Modules/main/data.json";function C(e){let t=e.toLowerCase(),n=/^(week|module|unit) \d{1,2}(?=.?)/,c=t.match(n),o=c?c[0]:null;return t.includes("start here")?"START HERE":o?"Week "+o.split(" ")[1]:null}function N(e){let t=document.createElement("div"),n=document.createElement("div");return t.className="ccau_modal",t.style.position="fixed",t.style.top="0",t.style.left="0",t.style.width="100%",t.style.height="100%",t.style.backgroundColor="rgba(0, 0, 0, 0.5)",t.style.display="flex",t.style.justifyContent="center",t.style.alignItems="center",t.style.zIndex="1000",n.classList.add("ccau_modal_content"),n.classList.add("ui-dialog"),n.classList.add("ui-widget"),n.classList.add("ui-widget-content"),n.classList.add("ui-corner-all"),n.classList.add("ui-dialog-buttons"),n.style.padding="20px",n.style.textAlign="center",document.body.appendChild(t),t.appendChild(n),n.appendChild(e),t}function R(){let e=localStorage.getItem("ccau_data")??"{}",t=JSON.parse(e);return Object.keys(t.dates).map(c=>{let o=document.createElement("button");return o.textContent=c,o.classList.add("ccau_semester_button"),o.classList.add("btn"),o.style.margin="5px",o})}function T(e){let t=JSON.parse(localStorage.getItem("ccau_data")||"{}");return Object.keys(t.ranges[e]).map(c=>{let o=document.createElement("button");return o.textContent=c,o.classList.add("ccau_term_button"),o.classList.add("btn"),o.style.margin="5px",o})}function q(e){let t=".ccau_semester_button";Array.from(document.querySelectorAll(t)).forEach(r=>r.remove());let c=T(e),o=document.querySelector(".ccau_modal_content");if(!o){a("Can't add buttons to null modal");return}c.forEach(r=>o.appendChild(r))}async function E(){let e=document.createElement("div"),t=R(),n=document.createElement("div");n.textContent="Which semester is this course?",e.appendChild(n);let c=null,o=null;return new Promise(r=>{let s=d=>{d.addEventListener("click",()=>{o=d.textContent,r([c,o]),m.remove()})},h=d=>{d.addEventListener("click",()=>{c=d.textContent,q(c||""),Array.from(document.querySelectorAll(".ccau_term_button")).map(B=>B).forEach(s)}),e.appendChild(d)};t.forEach(h);let m=N(e)})}function M(){let e="ccau_update_time",t="ccau_data_ts",n=Number(localStorage.getItem(e));!localStorage.getItem(t)&&n&&(localStorage.setItem(t,n.toString()),localStorage.removeItem(e))}function $(){M();let e=1e3*60*60*24,t=Date.now(),n=Number(localStorage.getItem("ccau_data_ts"))??0;t-n<e||fetch(A).then(c=>c.json()).then(c=>{localStorage.setItem("ccau_data",JSON.stringify(c)),localStorage.setItem("ccau_data_ts",t.toString())})}function j(e){let n=JSON.parse(localStorage.getItem("ccau_data")||"{}").dates[e];return n||(a(`No dates found for ${e}`),null)}function H(e,t){let c=JSON.parse(localStorage.getItem("ccau_data")||"{}").ranges[e][t];return c||(a(`No range found for ${e} ${t}`),null)}function J(e,t){return t.split(",").flatMap(n=>{let c=n.split("-").map(Number),o=c[0],r=c[1];return e.slice(o-1,r||o)})}function W(e){let t={};for(let n=0;n<e.length;n++)t[`Week ${n+1}`]=e[n];return t}async function v(){return new Promise(e=>{$(),E().then(async([t,n])=>{if(!t||!n){e({});return}let c=j(t),o=H(t,n);if(!c||!o){e({});return}let r=J(c,o);e(W(r))})})}function U(){let e="#add_module_item_select",n=document.querySelector(e);Array.from(n.options)?.forEach(o=>o.value="context_module_sub_header")}function z(){_([3,1,0],e=>{})}function P(e,t){let c=document.querySelector(e);c.value=t}async function F(){k(),U();let e=await v(),t=i(),n=p("START HERE",1),c=n===-1?t.length:n;for(let o=0;o<c;o++){let r=t[o].title,s=C(r);if(!s||!e[s]){a(`No date found for ${s??r}`);continue}g(p(s),2),P("#sub_header_title",e[s]),b(".add_item_button")}setTimeout(z,1500)}function w(){f("Add Dates",F,".header-bar-right__buttons")}function S(e){let n=i()[e].parentElement?.parentElement;return u(n,[2,0])?.children.length===0}function L(e){let t="__reactEventHandler";return Object.keys(e).find(o=>o.startsWith(t))}function G(){let e=".ui-kyle-menu",t=Array.from(document.querySelectorAll(e)),n=t.length;for(let c=0;c<n;c++){if(t[c].getAttribute("aria-hidden")!=="false")continue;let o=t[c];u(o,[4,0])?.click()}}function K(){let e=y(),n=i().length;for(let c=0;c<n-1;c++)S(c)&&(g(c,3),G());x(e)}function I(){f("Remove Empty",K,".header-bar-right__buttons")}function Q(){let e=".ui-kyle-menu",t=Array.from(document.querySelectorAll(e)),n=t.length;for(let c=0;c<n;c++){if(t[c].getAttribute("aria-hidden")!=="false")continue;let o=t[c];u(o,[2,0])?.click()}}function V(e){let t=document.querySelector(".move-select-form"),n=Array.from(t?.options??[]),c=n.length;if(!t)return a("Form not found"),!1;for(let o=0;o<c;o++){let r=n[o],s=L(t),h=t[s??""],m={target:{value:r.value}};if(r.text===e)return t.selectedIndex=o,t.value=n[o].value,h.onChange(m),!0}return!1}function X(){let e=p("START HERE",1),t=i(),n=t.length;if(e===-1){a("START HERE not found, add it to fix");return}for(let c=e;c<n;c++){let o=t[c].title,r=C(o),s=p(o,e);if(!r){a(`${o} does not match the expected format`);continue}if(S(c)){a(`Skipping ${r} because it's empty`);continue}if(g(s,3),Q(),!V(r)){a(`No destination selected for ${r}`);continue}b("#move-item-tray-submit-button")}}function O(){f("Auto-Move",X,".header-bar-right__buttons")}function Y(){if(!document.querySelector("#global_nav_accounts_link")){a("Only admins can use this script");return}w(),I(),O()}Y();})();