Skip to content

Commit e44e61e

Browse files
committed
Deprecate using transcript page as file naming source
As per the exploit mentioned in 0f595a7, it is decided to shift file and folder generation to use data provided in the course info. Without logging in transcripts can't be taken, therefore breaking the process. For now, slides ("exercise files") download are being looked into.
1 parent 84a8cf5 commit e44e61e

File tree

5 files changed

+93
-195
lines changed

5 files changed

+93
-195
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ or [![Buy me a coffee via Grab?](https://img.shields.io/badge/-Buy%20me%20a%20co
3030
- Check `preserve log` and `disable cache`.
3131
- Clear the current captured data.
3232
1. In the course page, refresh the page with the description. You should see stuff going in Developer Tools network tab. You have now caputured data for course information output.
33-
1. Navigate to the course "transcript" page. You have now captured data for transcript output.
3433
1. You may now export the HAL file and close the Developer Tool window.
3534
1. Run the program with the following command:
3635
```
@@ -55,7 +54,7 @@ __[Method 2, untested for resiliency]__ Continuing from previous section (Gettin
5554
```
5655
node ./main.js --videoDownload path_to_HAL_file
5756
```
58-
1. An output of all the video URLs will be in the `./output/videoList.json` file, and if you specified the `--videoDownload` parameter, videos will be downloaded alongside the subtitle files.
57+
1. An output of all the video URLs will be in the `./output/URLs.json` file, and if you specified the `--videoDownload` parameter, videos will be downloaded alongside the subtitle files.
5958
1. <strike> Copy the links and paste into any downloader (or browser window) to download the videos. Do note that you would need to manually rename the files.</strike>
6059
6160

functions/converter.js

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -33,35 +33,6 @@ function secsConvert(secs) {
3333
return myObject;
3434
}
3535

36-
/**
37-
* Converts object item to SRT string.
38-
* @param {array} transcript Object containing transcript information.
39-
*/
40-
function objToSRT(transcript) {
41-
return new Promise((resolve, reject) => {
42-
var stringBuffer = [];
43-
// console.log(transcript);
44-
// Sort the transcripts so that they are in the correct order
45-
transcript.sort((a, b) => {
46-
return a.seconds - b.seconds;
47-
});
48-
49-
// Outputs the JSON to srt format
50-
transcript.forEach((value, index) => {
51-
stringBuffer += index + "\n";
52-
stringBuffer += value.startTime.hours + ":" + value.startTime.minutes + ":" + value.startTime.seconds.replace(".", ",");
53-
stringBuffer += " --> ";
54-
stringBuffer += value.endTime.hours + ":" + value.endTime.minutes + ":" + value.endTime.seconds.replace(".", ",") + "\n";
55-
stringBuffer += " " + value.text + "\n\n";
56-
});
57-
58-
// console.log(stringBuffer);
59-
60-
resolve(stringBuffer);
61-
})
62-
63-
}
64-
6536
/**
6637
* @param {number} num
6738
* @return {Promise<string>}
@@ -71,58 +42,3 @@ module.exports.secsConvert = (num) => {
7142
resolve(secsConvert(num));
7243
});
7344
}
74-
75-
module.exports.objToSRT = (obj) => {
76-
// console.log(obj);
77-
return new Promise((resolve, reject) => {
78-
resolve(objToSRT(obj));
79-
})
80-
}
81-
82-
function transcriptToArr(item) {
83-
return new Promise((resolve, reject) => {
84-
let transcript = [];
85-
// Create a transcript object.
86-
item.segments.forEach((segment, index) => {
87-
88-
/**
89-
* @param {Object} startTime Start time of subtitle.
90-
* @param {Object} endTime End time of subtitle.
91-
* @param {number} seconds Time of subtitle in seconds.
92-
* @param {string} text Transcript content.
93-
*/
94-
var line = {
95-
"startTime": {},
96-
"endTime": {},
97-
"seconds": segment.displayTime,
98-
"text": segment.text
99-
};
100-
101-
const startTimePromise = secsConvert(segment.displayTime);
102-
103-
// If it is the last subtitle, add 3 seconds to compute its endtime.
104-
let endTimePromise;
105-
if ((index + 1) == item.segments.length) {
106-
endTimePromise = secsConvert(segment.displayTime + 3);
107-
} else {
108-
endTimePromise = secsConvert(item.segments[index + 1].displayTime);
109-
}
110-
111-
Promise.all([startTimePromise, endTimePromise]).then(promises => {
112-
line.startTime = promises[0];
113-
line.endTime = promises[1];
114-
transcript.push(line);
115-
});
116-
117-
});
118-
resolve(transcript);
119-
});
120-
121-
}
122-
123-
module.exports.transcriptToArr = (item) => {
124-
return new Promise((resolve, reject) => {
125-
resolve(transcriptToArr(item));
126-
127-
})
128-
}

functions/fileLister.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
const fs = require('fs');
2+
const converter = require('./converter.js');
3+
const func = require('./functions.js');
4+
5+
function fileNameSanitizer(fileName) {
6+
return fileName
7+
.replace(/\?/g, "")
8+
.replace(/\:/g, "-")
9+
.replace(//g, "")
10+
.replace(/\//g, "")
11+
.replace(/\\/g, "");
12+
}
13+
14+
function generatePaths(courseInfo) {
15+
return new Promise(async (resolve, reject) => {
16+
var videoList = [];
17+
await courseInfo.modules.forEach((module, index) => {
18+
// Output transcript based on folder
19+
var courseIndex = ++index;
20+
var folderName = ".\/output\/" + fileNameSanitizer(courseInfo.title) + "\/";
21+
22+
// Create course output directory if it doesn't exist
23+
if (!fs.existsSync(folderName)) {
24+
try {
25+
fs.mkdirSync(folderName.slice(0, -1));
26+
} catch (err) {
27+
console.log(err);
28+
}
29+
}
30+
31+
// Generate subfolder name.
32+
folderName = folderName.concat(func.numString(courseIndex));
33+
folderName = folderName + " - " + fileNameSanitizer(module.title);
34+
35+
// Generate subfolder
36+
if (!fs.existsSync(folderName)) {
37+
try {
38+
fs.mkdirSync(folderName);
39+
} catch (err) {
40+
console.log(err.message);
41+
}
42+
}
43+
44+
// Add key to folder name.
45+
folderName += "11B42C394C6217C5135BF7E4AC23E";
46+
47+
module.clips.forEach((clip, fileIndex) => {
48+
// Generate file name
49+
var fileName = folderName + "\/";
50+
51+
// Append course index
52+
fileName += func.numString(courseIndex) + ".";
53+
54+
// Check for class index
55+
fileName += func.numString(fileIndex) + " - ";
56+
57+
fileName += fileNameSanitizer(clip.title);
58+
59+
videoList.push(fileName);
60+
61+
});
62+
63+
});
64+
65+
resolve(videoList);
66+
});
67+
}
68+
69+
/**
70+
* Generates output path and writes into videoList.json
71+
* @param {Object} courseInfo
72+
*/
73+
module.exports.generatePaths = (courseInfo) => {
74+
return new Promise(async (resolve, reject) => {
75+
generatePaths(courseInfo).then((videoList) => {
76+
fs.writeFileSync("./output/videoList.json", JSON.stringify(videoList, null, 2));
77+
resolve(videoList);
78+
});
79+
80+
});
81+
}

functions/transcript.js

Lines changed: 0 additions & 97 deletions
This file was deleted.

main.js

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
const transcript = require("./functions/transcript.js");
21
const courseInfo = require("./functions/courseinfo.js");
32
const paramProcessor = require("./functions/paramProcessor.js");
43
const video = require("./functions/video.js");
4+
const filelister = require("./functions/filelister.js");
55
const exec = require("child_process").execSync;
66
const fs = require("fs");
77

@@ -28,26 +28,25 @@ if (!fs.existsSync("./output")) {
2828
}
2929
}
3030

31-
// Generate transcript and video list.
32-
if (!params.noSubs) {
33-
const searchString = /https:\/\/app\.pluralsight\.com\/learner\/user\/courses.*transcript/;
34-
var obtainedTranscript = false
31+
// Generate video list
32+
if (!params.videoDownload) {
33+
const searchString = /https:\/\/app\.pluralsight\.com\/learner\/content\/courses.*/;
34+
var obtainedVideoList = false;
3535
try {
3636
myJSON.log.entries.forEach((element, index) => {
37-
if (!obtainedTranscript && searchString.test(element.request.url)) {
37+
if (!obtainedCourseInfo && searchString.test(element.request.url)) {
3838
const passedJSON = JSON.parse(element.response.content.text);
39-
transcript.local(passedJSON).then((videoList) => {
40-
fs.writeFileSync("./output/videoList.json", JSON.stringify(videoList, null, 2));
41-
console.log("Completed transcript output, total " + videoList.length + " videos.")
42-
});
43-
obtainedTranscript = true;
39+
filelister.generatePaths(passedJSON);
40+
41+
obtainedVideoList = true;
4442
}
4543
});
4644
} catch (err) {
4745
console.log(err.message);
48-
console.log("If you see this its probably because the HAR file you provided does not have a transcript, or that the format has changed.");
46+
console.log("If you see this its probably because the HAR file you provided does not have course info, or that the format has changed.");
4947
console.log("If you are sure that the format has changed, please attach your HAR file and open an issue here: https://github.com/kwongtn/CourseExtractor/issues");
5048
}
49+
5150
}
5251

5352
// Generate and write courseInfo to output

0 commit comments

Comments
 (0)