-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathieee_sscs_download.js
More file actions
261 lines (232 loc) · 10.4 KB
/
Copy pathieee_sscs_download.js
File metadata and controls
261 lines (232 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
// ==UserScript==
// @name IEEE SSCS Resource Center Auto Downloader
// @namespace http://tampermonkey.net/
// @version 0.10
// @description Auto-download videos, slides, and transcripts from IEEE SSCS Resource Center (if you have access to)
// @author Rarity
// @match https://resourcecenter.sscs.ieee.org/education/*
// @grant GM_download
// @grant GM_notification
// @grant GM_xmlhttpRequest
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// ==/UserScript==
(function () {
'use strict';
// Configuration with default value
let downloadMode = GM_getValue('downloadMode', 'auto'); // Default: auto
let resourcesFound = { // Keep track of found resources
video: false,
slides: false,
transcript: false
};
// Register menu commands for user settings
GM_registerMenuCommand('Set Download Mode: Pause Sniffing', () => {
GM_setValue('downloadMode', 'pause');
downloadMode = 'pause';
alert('Download mode set to: Pause Sniffing');
});
GM_registerMenuCommand('Set Download Mode: Notify for Manual Download', () => {
GM_setValue('downloadMode', 'notify');
downloadMode = 'notify';
alert('Download mode set to: Notify for Manual Download');
});
GM_registerMenuCommand('Set Download Mode: Automatic Download', () => {
GM_setValue('downloadMode', 'auto');
downloadMode = 'auto';
alert('Download mode set to: Automatic Download');
});
function sanitizeFilename(str) {
return str.replace(/[/\\?%*:|"<>]/g, '-');
}
function extractResourceID(str) {
const match = str.match(/SSCS[A-Z]*\d+/i);
return match ? match[0] : '';
}
function extractVideoInfo(iframeDocument) {
console.log("extractVideoInfo called");
const videoTitle = document.querySelector('.card-title a span')?.textContent;
const author = document.querySelector('.h4.fw-normal')?.textContent;
// Extract resourceID from various possible sources
let resourceID = '';
if (iframeDocument) {
const poster = iframeDocument.querySelector('video')?.getAttribute('poster');
if (poster) {
resourceID = extractResourceID(poster);
}
}
if (!resourceID) {
const pdfLink = document.querySelector('.download-pdf a')?.href;
if (pdfLink) {
resourceID = extractResourceID(pdfLink);
}
}
// Extract year, prefer the first four digits of resourceID if it starts with SSCS, fallback to web page
let year = '';
if (resourceID.startsWith('SSCS')) {
const potentialYearMatch = resourceID.match(/\d{4}/); // Match the first 4-digit number
if (potentialYearMatch) {
const potentialYear = potentialYearMatch[0];
if (potentialYear >= 1950 && potentialYear <= new Date().getFullYear()) {
year = potentialYear;
}
}
}
if (!year) {
// Fallback: Extract year from the date string on the page
const dateString = document.querySelector('.card-text .col-12.mb-0.h5')?.textContent.trim();
const yearMatch = dateString.match(/\d{4}/); // Match a 4-digit number (year)
year = yearMatch ? yearMatch[0] : '';
}
console.log("Extracted Info:", { videoTitle, author, year, resourceID });
return { videoTitle, author, year, resourceID };
}
function getDownloadLink(iframeDocument) {
console.log("getDownloadLink called");
try {
const videoElement = iframeDocument.querySelector('video source');
if (videoElement) {
console.log("Video element found:", videoElement);
return videoElement.src;
} else {
console.log("Video element not found");
return null;
}
} catch (error) {
console.error("Error in getDownloadLink:", error);
return null;
}
}
function downloadResource(url, filename) {
console.log("downloadResource called with:", url, filename);
GM_xmlhttpRequest({
method: "GET",
url: url,
responseType: 'blob',
onload: function (response) {
if (response.status >= 200 && response.status < 300) {
const blob = response.response;
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} else {
console.error('Download error:', response.status, response.statusText);
GM_notification({
text: `Error downloading resource. Status: ${response.status}`,
title: 'Download Error',
timeout: 5000,
});
}
},
onerror: (err) => {
console.error('Download error:', err);
GM_notification({
text: 'Error downloading resource. Check console for details.',
title: 'Download Error',
timeout: 5000,
});
}
});
}
function handleResourceLoaded(resourceLink, resourceType, iframeDocument) {
console.log("handleResourceLoaded called with:", resourceLink, resourceType);
// Stop checking for this resource type
resourcesFound[resourceType] = true;
const { videoTitle, author, year, resourceID } = extractVideoInfo(iframeDocument);
const extension = resourceLink.split('.').pop().split('?')[0];
// Sanitize the filename components
const sanitizedTitle = sanitizeFilename(videoTitle);
const sanitizedAuthor = sanitizeFilename(author);
// Determine conference type based on resourceID
let conferenceType = "ISSCC"; // Default to ISSCC
if (resourceID.toUpperCase().includes("SSCS")) {
if (resourceID.toUpperCase().includes("SSCSCICC")) {
conferenceType = "CICC";
} else if (resourceID.toUpperCase().includes("SSCSVLSI")) {
conferenceType = "VLSI";
}
}
// Construct the filename
let filename = `${conferenceType} ${year} - Tx - ${sanitizedTitle}, ${sanitizedAuthor}`;
if (resourceID) {
filename += `, ${resourceID}`;
}
filename += `.${extension}`;
if (downloadMode === 'auto') {
downloadResource(resourceLink, filename);
} else if (downloadMode === 'notify') {
GM_notification({
text: `${resourceType.toUpperCase()} found: ${filename}\nClick to download.`,
title: `${resourceType.toUpperCase()} Download Ready`,
timeout: 10000,
onclick: () => {
downloadResource(resourceLink, filename);
}
});
} else if (downloadMode === 'pause') {
console.log("Sniffing paused. No action taken.");
}
}
// Function to check for resources periodically
function checkForResources() {
if (downloadMode === 'pause') {
console.log("Sniffing paused. Skipping resource check.");
return; // Skip checking if paused
}
const iframeElement = document.querySelector('.product-accessible iframe');
//Slides and Transcripts are PDF files
const pdfLinkElement = document.querySelector('.download-pdf a');
// Handle Video
if (iframeElement && !resourcesFound.video) {
console.log("iframe found:", iframeElement);
const iframeDocument = iframeElement.contentDocument || iframeElement.contentWindow.document;
const videoLink = getDownloadLink(iframeDocument);
if (videoLink) {
handleResourceLoaded(videoLink, 'video', iframeDocument);
} else {
const observer = new MutationObserver((mutations) => {
console.log("MutationObserver triggered:", mutations);
const updatedVideoLink = getDownloadLink(iframeDocument);
if (updatedVideoLink) {
handleResourceLoaded(updatedVideoLink, 'video', iframeDocument);
observer.disconnect(); // Stop observing after finding the video
}
});
const targetNode = document.querySelector('.product-accessible');
if (targetNode) {
console.log("Starting MutationObserver on specific target");
observer.observe(targetNode, { childList: true, subtree: true });
console.log("MutationObserver started");
} else {
console.log("Target node '.product-accessible' not found. Observing document.body instead.");
observer.observe(document.body, { childList: true, subtree: true });
console.log("MutationObserver started on document.body");
}
}
}
// Handle Slides and Transcripts
if (pdfLinkElement && (!resourcesFound.slides || !resourcesFound.transcript)) {
const pdfLink = pdfLinkElement.href;
// Check if the link is for slides or transcript based on URL or filename
if (pdfLink.includes('slides')) {
if (!resourcesFound.slides) {
handleResourceLoaded(pdfLink, 'slides', null);
}
} else {
// Assuming any other PDF link is a transcript if not identified as slides
if (!resourcesFound.transcript) {
handleResourceLoaded(pdfLink, 'transcript', null);
}
}
}
}
// Start checking for resources periodically
console.log("Starting interval to check for resources");
const resourceCheckInterval = setInterval(checkForResources, 500); // Check every 500ms
console.log("Interval started");
})();