KIITConnect Data Management

Adds a settings menu for downloading data, uploading data, and downloading a file

当前为 2024-11-12 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         KIITConnect Data Management
// @namespace    http://tampermonkey.net/
// @version      1.0
// @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';

    // 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/mb7Btvbb5wbskpNy6', '_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://1drv.ms/x/s!AiNuwFrvg4udgo9BKbM_MQymtYnGnQ?e=8uIuu5', '_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() : '';

                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() || '';

                // Add row data to the allSubjectsData array with subject name included
                allSubjectsData.push({
                    subject: subjectName,
                    year: pyqYear,
                    type: pyqType,
                    pyqName: pyqName,
                    pyqLink: pyqLink,
                    solutionLink: pyqSolutionLink,
                    solution: solution,
                    solutionStatus: solutionStatusText
                });
            });
        });

        // Function to convert JSON to CSV format
        function convertToCSV(data) {
            const headers = ['Subject', 'Year', 'Type', 'PYQ Name', 'PYQ Link', 'Solution Link', 'Solution', 'Solution Status'];
            const rows = data.map(row => [
                row.subject,
                row.year,
                row.type,
                row.pyqName,
                row.pyqLink,
                row.solutionLink,
                row.solution,
                row.solutionStatus
            ]);
            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();
    }
})();