PDF Downloader for Dr Najeeb Lectures

Automatically downloads PDF files from course pages

Size

7.0 KB

Version

1.2.3

Created

Nov 7, 2025

Updated

about 1 month ago

1// ==UserScript==
2// @name		PDF Downloader for Dr Najeeb Lectures
3// @description		Automatically downloads PDF files from course pages
4// @version		1.2.3
5// @match		https://*.members.drnajeeblectures.com/*
6// @icon		https://members.drnajeeblectures.com/favicon.ico
7// @grant		GM.xmlhttpRequest
8// @require		https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js
9// ==/UserScript==
10(function() {
11    'use strict';
12
13    console.log('PDF Downloader extension loaded');
14
15    // Function to capture all pages and create PDF
16    async function captureAndDownloadPDF(filename) {
17        console.log('Starting PDF capture process...');
18        
19        try {
20            const iframe = document.querySelector('#text iframe');
21            if (!iframe) {
22                alert('PDF viewer not found');
23                return;
24            }
25
26            const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
27            const canvas = iframeDoc.querySelector('canvas');
28            const pageCountEl = iframeDoc.querySelector('#page_count');
29            const pageNumInput = iframeDoc.querySelector('#page_num');
30            const nextBtn = iframeDoc.querySelector('#next');
31            
32            if (!canvas || !pageCountEl || !pageNumInput || !nextBtn) {
33                alert('Could not access PDF viewer elements');
34                return;
35            }
36
37            const totalPages = parseInt(pageCountEl.textContent);
38            console.log('Total pages to capture:', totalPages);
39
40            // Make sure we start from page 1
41            pageNumInput.value = 1;
42            const changeEvent = new Event('change', { bubbles: true });
43            pageNumInput.dispatchEvent(changeEvent);
44            await new Promise(resolve => setTimeout(resolve, 2000));
45
46            // Create new PDF document
47            const { jsPDF } = window.jspdf;
48            const pdf = new jsPDF({
49                orientation: canvas.height > canvas.width ? 'portrait' : 'landscape',
50                unit: 'px',
51                format: [canvas.width, canvas.height]
52            });
53
54            // Capture each page
55            for (let pageNum = 1; pageNum <= totalPages; pageNum++) {
56                console.log(`Capturing page ${pageNum}/${totalPages}...`);
57                
58                // Wait for page to render
59                await new Promise(resolve => setTimeout(resolve, 1500));
60                
61                // Capture canvas as image in high quality PNG
62                const imgData = canvas.toDataURL('image/png', 1.0);
63                
64                // Add page to PDF (first page is already created)
65                if (pageNum > 1) {
66                    pdf.addPage([canvas.width, canvas.height]);
67                }
68                
69                pdf.addImage(imgData, 'PNG', 0, 0, canvas.width, canvas.height);
70                console.log(`Page ${pageNum} captured`);
71                
72                // Navigate to next page (if not last page)
73                if (pageNum < totalPages) {
74                    nextBtn.click();
75                    console.log('Clicked next button');
76                }
77            }
78
79            // Save the PDF
80            console.log('Saving PDF...');
81            pdf.save(filename);
82            console.log('PDF saved successfully!');
83            
84            // Reset to first page
85            pageNumInput.value = 1;
86            pageNumInput.dispatchEvent(new Event('change', { bubbles: true }));
87
88        } catch (error) {
89            console.error('Error creating PDF:', error);
90            alert('Failed to create PDF: ' + error.message);
91        }
92    }
93
94    // Function to extract course name for filename
95    function getCourseName() {
96        const titleElement = document.querySelector('h3.text-ellipsis');
97        if (titleElement) {
98            return titleElement.textContent.trim().replace(/[^a-z0-9]/gi, '_').substring(0, 50);
99        }
100        return 'course_notes';
101    }
102
103    // Function to create download button
104    function createDownloadButton() {
105        const iframe = document.querySelector('#text iframe');
106        
107        if (!iframe) {
108            console.log('No PDF iframe found on this page');
109            return;
110        }
111
112        const buttonContainer = document.querySelector('.s-title .column.col-7');
113        
114        if (!buttonContainer) {
115            console.log('Button container not found');
116            return;
117        }
118
119        // Check if button already exists
120        if (document.getElementById('pdfDownloadBtn')) {
121            console.log('Download button already exists');
122            return;
123        }
124
125        // Create download button
126        const downloadBtn = document.createElement('button');
127        downloadBtn.id = 'pdfDownloadBtn';
128        downloadBtn.className = 'btn btn-link courseNavBtn';
129        downloadBtn.innerHTML = `
130            <i class="material-icons" style="vertical-align: middle;">download</i>
131            <span class="icon-text">Download PDF</span>
132        `;
133        downloadBtn.style.cssText = `
134            color: rgb(87, 85, 217);
135            padding: 7px 8px;
136            font-size: 16px;
137            font-family: Inter, sans-serif;
138            border: none;
139            background: transparent;
140            cursor: pointer;
141            margin-right: 10px;
142        `;
143
144        // Add hover effect
145        downloadBtn.addEventListener('mouseenter', () => {
146            downloadBtn.style.opacity = '0.7';
147        });
148        downloadBtn.addEventListener('mouseleave', () => {
149            downloadBtn.style.opacity = '1';
150        });
151
152        // Add click handler
153        downloadBtn.addEventListener('click', async () => {
154            downloadBtn.disabled = true;
155            downloadBtn.innerHTML = `
156                <i class="material-icons" style="vertical-align: middle;">hourglass_empty</i>
157                <span class="icon-text">Creating PDF...</span>
158            `;
159            
160            const courseName = getCourseName();
161            const filename = `${courseName}.pdf`;
162            
163            await captureAndDownloadPDF(filename);
164            
165            // Reset button after download
166            setTimeout(() => {
167                downloadBtn.disabled = false;
168                downloadBtn.innerHTML = `
169                    <i class="material-icons" style="vertical-align: middle;">download</i>
170                    <span class="icon-text">Download PDF</span>
171                `;
172            }, 1000);
173        });
174
175        // Insert button before the "Previous" button
176        const prevButton = document.getElementById('prevCourseItemBtn');
177        buttonContainer.insertBefore(downloadBtn, prevButton);
178        
179        console.log('Download button added successfully');
180    }
181
182    // Wait for page to load and add button
183    function init() {
184        console.log('Initializing PDF downloader...');
185        
186        // Wait for the page to fully load
187        setTimeout(() => {
188            createDownloadButton();
189        }, 2000);
190    }
191
192    // Run when page is ready
193    if (document.readyState === 'loading') {
194        document.addEventListener('DOMContentLoaded', init);
195    } else {
196        init();
197    }
198
199})();
PDF Downloader for Dr Najeeb Lectures | Robomonkey