- // ==UserScript==
- // @name KIITConnect Data Management
- // @namespace http://tampermonkey.net/
- // @version 1.6
- // @description Adds a settings menu for downloading data, uploading data, and downloading a file
- // @author Bibek
- // @match https://www.kiitconnect.com/*
- // @grant none
- // @icon https://www.kiitconnect.com/favicon.ico
- // @license MIT
- // ==/UserScript==
-
- (function () {
- 'use strict';
-
- const filenameDivSelector = '.flex.w-full.pt-10.md\\:pt-0.pb-6.text-base.mt-5.md\\:py-10.md\\:my-0.font-bold.md\\:text-2xl.justify-center.items-center span.pl-2';
-
- // Ensure the filename div is detected
- function ensureFilenameDivLoaded(callback) {
- const retryInterval = 100; // Check every 100ms
- const maxRetries = 50; // Limit retries to avoid infinite loop
- let retries = 0;
-
- const interval = setInterval(() => {
- const filenameDiv = document.querySelector(filenameDivSelector);
- if (filenameDiv) {
- clearInterval(interval);
- callback(filenameDiv);
- } else if (++retries >= maxRetries) {
- clearInterval(interval);
- console.error('Filename div not found within the retry limit.');
- }
- }, retryInterval);
- }
-
- // Function to handle PYQS functionality
- function executePYQsCode() {
- // alert("Now looking for PYQs.");
- console.log('Executing PYQS functionality...');
- // Your existing PYQS logic here
- // Function to create and insert the settings icon and menu
- function createSettingsMenu() {
- // Create settings icon
- const settingsIcon = document.createElement('img');
- settingsIcon.src = 'https://cdn-icons-png.flaticon.com/512/2697/2697990.png';
- settingsIcon.alt = 'Settings';
- settingsIcon.style.width = '40px';
- settingsIcon.style.cursor = 'pointer';
- settingsIcon.style.position = 'fixed';
- settingsIcon.style.bottom = '20px';
- settingsIcon.style.right = '20px';
- settingsIcon.style.zIndex = '1000';
-
- // Create menu container
- const menuContainer = document.createElement('div');
- menuContainer.style.display = 'none';
- menuContainer.style.flexDirection = 'column';
- menuContainer.style.position = 'fixed';
- menuContainer.style.bottom = '70px';
- menuContainer.style.right = '10px';
- menuContainer.style.backgroundColor = '#041d35';
- menuContainer.style.backdropFilter = 'blur(5px)';
- menuContainer.style.padding = '10px';
- menuContainer.style.border = '1px solid #143267';
- menuContainer.style.borderRadius = '50px';
- menuContainer.style.zIndex = '1000';
-
- // Toggle menu visibility on settings icon click
- settingsIcon.addEventListener('click', () => {
- menuContainer.style.display = menuContainer.style.display === 'none' ? 'flex' : 'none';
- });
-
- // Create download CSV icon
- const downloadCSVIcon = document.createElement('img');
- downloadCSVIcon.src = 'https://cdn-icons-png.flaticon.com/512/9153/9153957.png';
- downloadCSVIcon.alt = 'Download CSV';
- downloadCSVIcon.style.width = '40px';
- downloadCSVIcon.style.cursor = 'pointer';
- downloadCSVIcon.style.marginBottom = '10px';
- downloadCSVIcon.addEventListener('click', downloadCSVData);
-
- // Create upload icon (opens Google Form)
- const uploadIcon = document.createElement('img');
- uploadIcon.src = 'https://cdn-icons-png.flaticon.com/512/10152/10152423.png';
- uploadIcon.alt = 'Upload';
- uploadIcon.style.width = '40px';
- uploadIcon.style.cursor = 'pointer';
- uploadIcon.style.marginBottom = '10px';
- uploadIcon.addEventListener('click', () => {
- window.open('https://forms.gle/sb4uEPXWmhCvRcBG6', '_blank');
- });
-
- // Create download file icon
- const downloadFileIcon = document.createElement('img');
- downloadFileIcon.src = 'https://cdn-icons-png.flaticon.com/512/1091/1091007.png';
- downloadFileIcon.alt = 'Download File';
- downloadFileIcon.style.width = '40px';
- downloadFileIcon.style.cursor = 'pointer';
- downloadFileIcon.addEventListener('click', () => {
- window.open('https://drive.google.com/drive/folders/11FZF-h8tmulA9LgLLV9E4s2LbGD_Rf7iI5BwCl35WdZ-vfbuQzDZcGgP1IwiwkRVJ-rK0uoU?usp=sharing', '_blank');
- });
-
- // Append icons to menu container
- menuContainer.appendChild(downloadCSVIcon);
- menuContainer.appendChild(uploadIcon);
- menuContainer.appendChild(downloadFileIcon);
-
- // Append settings icon and menu container to document body
- document.body.appendChild(settingsIcon);
- document.body.appendChild(menuContainer);
- }
-
- // Function to scrape data and download as CSV
- function downloadCSVData() {
- // Retrieve the filename from the specific div
- const filenameDiv = document.querySelector('.flex.w-full.pt-10.md\\:pt-0.pb-6.text-base.mt-5.md\\:py-10.md\\:my-0.font-bold.md\\:text-2xl.justify-center.items-center span.pl-2');
- const filename = filenameDiv ? filenameDiv.textContent.trim() : 'subject_data';
-
- // Initialize an array to hold all subjects with their respective rows
- const allSubjectsData = [];
-
- // Select all subject name elements
- const subjectNameElements = document.querySelectorAll('.py-3.md\\:py-5.relative.rounded-md.text-\\[12px\\].md\\:text-2xl.font-bold.text-center.border.border-slate-500.text-gray-300');
-
- // Iterate over each subject name element
- subjectNameElements.forEach(subjectElement => {
- // Extract the subject name
- const subjectName = subjectElement.textContent.trim().replace(/^Syllabus\s*/, '');
-
- // Select the table rows within this subject
- const rows = subjectElement.nextElementSibling.querySelectorAll('tbody.text-white.text-base tr');
-
- // Iterate over each row within the subject
- rows.forEach(row => {
- // Extract row data
- const pyqYear = row.querySelector('td.whitespace-nowrap.px-6.font-bold.py-4.text-slate-300')?.textContent.trim() || '';
- const pyqType = row.querySelector('td.whitespace-nowrap.px-6.text-gray-400.font-bold.hidden.md\\:block.py-4')?.textContent.trim() || '';
-
- const pyqLinkElement = row.querySelector('td.whitespace-nowrap.px-6.py-4 a.font-bold.text-cyan-500');
- const pyqLink = pyqLinkElement ? pyqLinkElement.href : '';
- const pyqName = pyqLinkElement ? pyqLinkElement.textContent.trim() : '';
-
- // Extract the last 33 characters of the question code from the link
- // const questionCode = pyqLink ? pyqLink.match(/academic\/view\/([a-zA-Z0-9_-]{33})\?/)[1] : '';
- const questionCode = pyqLink ? (pyqLink.match(/([a-zA-Z0-9_-]{33})\?/)?.[1] || '') : '';
-
- const pyqSolutionLinkElement = row.querySelector('td.whitespace-nowrap.px-6.py-4.font-bold.text-gray-400 a.text-cyan-500');
- const pyqSolutionLink = pyqSolutionLinkElement ? pyqSolutionLinkElement.href : '';
- const solutionTextElement = row.querySelector('td.whitespace-nowrap.px-6.py-4.font-bold.text-gray-400 span');
- const solution = pyqSolutionLinkElement
- ? pyqSolutionLinkElement.textContent.trim()
- : (solutionTextElement ? solutionTextElement.textContent.trim() : 'Not Available');
-
- // Get the additional solutionStatus text
- const solutionStatusText = row.querySelector('td.whitespace-nowrap.px-6.py-4.font-bold.text-gray-400')?.textContent.trim() || '';
-
- const solutionCode = pyqSolutionLink ? (pyqSolutionLink.match(/([a-zA-Z0-9_-]{33})\?/)?.[1] || '') : ''; // new line
-
- // Add row data to the allSubjectsData array with subject name included
- allSubjectsData.push({
- subject: subjectName,
- year: pyqYear,
- type: pyqType,
- pyqName: pyqName,
- pyqLink: pyqLink,
- questionCode: questionCode,// Add question code here
- solutionLink: pyqSolutionLink,
- solution: solution,
- solutionStatus: solutionStatusText,
- solutionCode: solutionCode,
- });
- });
- });
-
- // Function to convert JSON to CSV format
- function convertToCSV(data) {
- const headers = [
- 'Subject',
- 'Year',
- 'Type',
- 'PYQ Name',
- 'PYQ Link',
- 'Question Code',
- 'Solution Link',
- 'Solution',
- 'Solution Status',
- 'solutionCode',
- 'Question Link', // New column header
- 'Solution Link' // New column header
- ];
-
- const rows = data.map(row => [
- row.subject,
- row.year,
- row.type,
- row.pyqName,
- row.pyqLink,
- row.questionCode,
- row.solutionLink,
- row.solution,
- row.solutionStatus,
- row.solutionCode,
-
- // Question Link
- row.questionCode
- ? `=HYPERLINK("https://drive.google.com/file/d/${row.questionCode}/edit", "${row.year} ${row.pyqName}")`.replace(/"/g, '""')
- : 'Not Available',
- // Solution Link
- row.solutionCode
- ? `=HYPERLINK("https://drive.google.com/file/d/${row.solutionCode}/edit", "${row.year} ${row.pyqName} Solution")`.replace(/"/g, '""')
- : 'Not Available'
-
- ]);
-
- // Convert rows to CSV format
- return [headers.join(','), ...rows.map(row => row.map(cell => `"${cell}"`).join(','))].join('\n');
- }
-
-
-
-
- // Convert the data to CSV format
- const csvData = convertToCSV(allSubjectsData);
-
- // Create a Blob from the CSV data and trigger the download
- const blob = new Blob([csvData], { type: 'text/csv' });
- const url = URL.createObjectURL(blob);
- const a = document.createElement('a');
- a.href = url;
- a.download = `${filename}.csv`;
- a.style.display = 'none';
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(url); // Clean up the URL object
- }
-
- // Run the script only on the specified page
- if (window.location.href.startsWith('https://www.kiitconnect.com/')) {
- createSettingsMenu();
- }
- }
-
- // Function to handle NOTES functionality
- function executeNOTESCode() {
- // alert("Now looking for NOTES.");
- console.log('Executing NOTES functionality...');
- // Your existing NOTES logic here
- // Function to create and insert the settings icon and menu
- function createSettingsMenu() {
- // Create settings icon
- const settingsIcon = document.createElement('img');
- settingsIcon.src = 'https://cdn-icons-png.flaticon.com/512/2697/2697990.png';
- settingsIcon.alt = 'Settings';
- settingsIcon.style.width = '40px';
- settingsIcon.style.cursor = 'pointer';
- settingsIcon.style.position = 'fixed';
- settingsIcon.style.bottom = '20px';
- settingsIcon.style.right = '20px';
- settingsIcon.style.zIndex = '1000';
-
- // Create menu container
- const menuContainer = document.createElement('div');
- menuContainer.style.display = 'none';
- menuContainer.style.flexDirection = 'column';
- menuContainer.style.position = 'fixed';
- menuContainer.style.bottom = '70px';
- menuContainer.style.right = '10px';
- menuContainer.style.backgroundColor = '#041d35';
- menuContainer.style.backdropFilter = 'blur(5px)';
- menuContainer.style.padding = '10px';
- menuContainer.style.border = '1px solid #143267';
- menuContainer.style.borderRadius = '50px';
- menuContainer.style.zIndex = '1000';
-
- // Toggle menu visibility on settings icon click
- settingsIcon.addEventListener('click', () => {
- menuContainer.style.display = menuContainer.style.display === 'none' ? 'flex' : 'none';
- });
-
- // Create download CSV icon
- const downloadCSVIcon = document.createElement('img');
- downloadCSVIcon.src = 'https://cdn-icons-png.flaticon.com/512/9153/9153957.png';
- downloadCSVIcon.alt = 'Download CSV';
- downloadCSVIcon.style.width = '40px';
- downloadCSVIcon.style.cursor = 'pointer';
- downloadCSVIcon.style.marginBottom = '10px';
- downloadCSVIcon.addEventListener('click', downloadCSVData);
-
- // Create upload icon (opens Google Form)
- const uploadIcon = document.createElement('img');
- uploadIcon.src = 'https://cdn-icons-png.flaticon.com/512/10152/10152423.png';
- uploadIcon.alt = 'Upload';
- uploadIcon.style.width = '40px';
- uploadIcon.style.cursor = 'pointer';
- uploadIcon.style.marginBottom = '10px';
- uploadIcon.addEventListener('click', () => {
- window.open('https://forms.gle/sb4uEPXWmhCvRcBG6', '_blank');
- });
-
- // Create download file icon
- const downloadFileIcon = document.createElement('img');
- downloadFileIcon.src = 'https://cdn-icons-png.flaticon.com/512/1091/1091007.png';
- downloadFileIcon.alt = 'Download File';
- downloadFileIcon.style.width = '40px';
- downloadFileIcon.style.cursor = 'pointer';
- downloadFileIcon.addEventListener('click', () => {
- window.open('https://drive.google.com/drive/folders/11FZF-h8tmulA9LgLLV9E4s2LbGD_Rf7iI5BwCl35WdZ-vfbuQzDZcGgP1IwiwkRVJ-rK0uoU?usp=sharing', '_blank');
- });
-
- // Append icons to menu container
- menuContainer.appendChild(downloadCSVIcon);
- menuContainer.appendChild(uploadIcon);
- menuContainer.appendChild(downloadFileIcon);
-
- // Append settings icon and menu container to document body
- document.body.appendChild(settingsIcon);
- document.body.appendChild(menuContainer);
- }
-
-
-
- function downloadCSVData() {
- // Retrieve the filename from the specific div
- const filenameDiv = document.querySelector('.flex.w-full.pt-10.md\\:pt-0.pb-6.text-base.mt-5.md\\:py-10.md\\:my-0.font-bold.md\\:text-2xl.justify-center.items-center span.pl-2');
- const filename = filenameDiv ? filenameDiv.textContent.trim() : 'data_export';
-
- // Initialize an array to hold all subjects with their respective rows
- const allSubjectsData = [];
-
- // Select all subject name elements
- const subjectNameElements = document.querySelectorAll('.py-3.md\\:py-5.relative.rounded-md.text-\\[12px\\].md\\:text-2xl.font-bold.text-center.border.border-slate-500.text-gray-300');
-
- // Iterate over each subject name element
- subjectNameElements.forEach(subjectElement => {
- // Extract the subject name and remove "Syllabus"
- const subjectName = subjectElement.textContent.trim().replace(/^Syllabus\s*/, '');
-
- // Select all topics under this subject
- const topics = subjectElement.parentElement.querySelectorAll('.text-cyan-500 h1');
- const topicLinks = subjectElement.parentElement.querySelectorAll('.cursor-pointer.py-3[href]');
-
- topics.forEach((topicElement, index) => {
- const topicName = topicElement.textContent.trim();
- const topicLink = topicLinks[index]?.href || '';
- const topicCode = topicLink ? (topicLink.match(/([a-zA-Z0-9_-]{33})(?=\?)/)?.[1] || '') : '';
-
- // Add topic data to the allSubjectsData array with subject name included
- allSubjectsData.push({
- subject: subjectName,
- topic: topicName,
- topicLink: topicLink,
- topicCode: topicCode,
- });
- });
- });
-
- // Function to convert JSON to CSV format
- function convertToCSV(data) {
- const headers = ['Subject', 'Topic Name', 'Topic Link', 'Topic Code', 'Note Link'];
- const rows = data.map(row => [
- row.subject,
- row.topic,
- row.topicLink,
- row.topicCode,
- `=HYPERLINK("https://drive.google.com/file/d/${row.topicCode}/edit", "${row.topic}")`.replace(/"/g, '""') // Escape double quotes
- ]);
-
- return [headers.join(','), ...rows.map(row => row.map(cell => `"${cell}"`).join(','))].join('\n');
- }
-
- // Convert the data to CSV format
- const csvData = convertToCSV(allSubjectsData);
-
- // Create a Blob from the CSV data and trigger the download
- const blob = new Blob([csvData], { type: 'text/csv' });
- const url = URL.createObjectURL(blob);
- const a = document.createElement('a');
- a.href = url;
- a.download = `${filename}.csv`;
- a.style.display = 'none';
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(url); // Clean up the URL object
- }
-
- // Run the script only on the specified page
- if (window.location.href.startsWith('https://www.kiitconnect.com/')) {
- createSettingsMenu();
- }
- }
-
- // Check and execute functionality based on filename div content
- function checkAndExecute(filenameDiv) {
- const textContent = filenameDiv.textContent.trim().toUpperCase();
- console.log('Filename text detected:', textContent);
-
- if (textContent.includes('PYQS')) {
- executePYQsCode();
- } else if (textContent.includes('NOTES')) {
- executeNOTESCode();
- } else {
- console.warn('Unrecognized filename text:', textContent);
- }
- }
-
- // Observe changes in the DOM and recheck
- function observeChanges(filenameDiv) {
- const observer = new MutationObserver(() => {
- console.log('Filename text content changed, rechecking...');
- checkAndExecute(filenameDiv);
- });
-
- observer.observe(filenameDiv, {
- characterData: true,
- subtree: true,
- childList: true
- });
-
- console.log('MutationObserver is now watching for changes.');
- }
-
- // Initialize script
- window.addEventListener('load', () => {
- ensureFilenameDivLoaded((filenameDiv) => {
- checkAndExecute(filenameDiv);
- observeChanges(filenameDiv);
- });
- });
- })();