Merge pull request #674 from GilgusMaximus/development

Comment scraper child process [Help needed]
This commit is contained in:
Luca Hohmann 2020-10-24 13:44:16 +02:00 committed by GitHub
commit a99bfd6a47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 129 additions and 69 deletions

View File

@ -111,6 +111,7 @@ const config = {
fs: 'empty', fs: 'empty',
net: 'empty', net: 'empty',
tls: 'empty', tls: 'empty',
child_process: 'empty'
}, },
plugins: [ plugins: [
// new WriteFilePlugin(), // new WriteFilePlugin(),

View File

@ -0,0 +1,23 @@
const ModuleScraper = require('yt-comment-scraper')
let scraper = null
let currentSort = null
let currentVideoId = null
process.on('message', (msg) => {
if (msg === 'end') {
process.exit(0)
}
if (msg.id !== currentVideoId || msg.sortNewest !== currentSort) {
if (scraper !== null) {
scraper.cleanupStatics()
}
currentSort = msg.sortNewest
currentVideoId = msg.id
scraper = new ModuleScraper(true, currentSort)
}
scraper.scrape_next_page_youtube_comments(currentVideoId).then((comments) => {
process.send({ comments: JSON.stringify(comments), error: null })
}).catch((error) => {
process.send({ comments: null, error: error })
})
})

View File

@ -5,7 +5,10 @@ import FtLoader from '../../components/ft-loader/ft-loader.vue'
import FtSelect from '../../components/ft-select/ft-select.vue' import FtSelect from '../../components/ft-select/ft-select.vue'
import FtTimestampCatcher from '../../components/ft-timestamp-catcher/ft-timestamp-catcher.vue' import FtTimestampCatcher from '../../components/ft-timestamp-catcher/ft-timestamp-catcher.vue'
import autolinker from 'autolinker' import autolinker from 'autolinker'
import CommentScraper from 'yt-comment-scraper' import { fork } from 'child_process'
import path from 'path'
// eslint-disable-next-line
import commentControllerRelativePath from 'file-loader!../../../process/comment-module-controller.js'
export default Vue.extend({ export default Vue.extend({
name: 'WatchVideoComments', name: 'WatchVideoComments',
@ -32,10 +35,16 @@ export default Vue.extend({
commentScraper: null, commentScraper: null,
nextPageToken: null, nextPageToken: null,
commentData: [], commentData: [],
sortNewest: false sortNewest: false,
commentProcess: null,
sortingChanged: false
} }
}, },
computed: { computed: {
isDev: function () {
return process.env.NODE_ENV === 'development'
},
backendPreference: function () { backendPreference: function () {
return this.$store.getters.getBackendPreference return this.$store.getters.getBackendPreference
}, },
@ -69,6 +78,12 @@ export default Vue.extend({
return (this.sortNewest) ? 'newest' : 'top' return (this.sortNewest) ? 'newest' : 'top'
} }
}, },
beforeDestroy: function () {
if (this.commentProcess !== null) {
this.commentProcess.send('end')
}
},
methods: { methods: {
onTimestamp: function (timestamp) { onTimestamp: function (timestamp) {
this.$emit('timestamp-event', timestamp) this.$emit('timestamp-event', timestamp)
@ -78,7 +93,9 @@ export default Vue.extend({
this.sortNewest = !this.sortNewest this.sortNewest = !this.sortNewest
switch (this.backendPreference) { switch (this.backendPreference) {
case 'local': case 'local':
this.getCommentDataLocal(true) console.log('In handle')
this.sortingChanged = true
this.getCommentDataLocal()
break break
case 'invidious': case 'invidious':
this.isLoading = true this.isLoading = true
@ -88,11 +105,11 @@ export default Vue.extend({
} }
}, },
getCommentData: function (sortChanged = false) { getCommentData: function () {
this.isLoading = true this.isLoading = true
switch (this.backendPreference) { switch (this.backendPreference) {
case 'local': case 'local':
this.getCommentDataLocal(sortChanged) this.getCommentDataLocal()
break break
case 'invidious': case 'invidious':
this.getCommentDataInvidious(this.nextPageToken) this.getCommentDataInvidious(this.nextPageToken)
@ -126,13 +143,24 @@ export default Vue.extend({
} }
}, },
getCommentDataLocal: function (sortChanged = false) { getCommentDataLocal: function () {
if (this.commentScraper === null || sortChanged === true) { // we need the path from the working directory to fork correctly
this.commentScraper = new CommentScraper(false, this.sortNewest) if (this.commentProcess === null) {
this.commentData = [] let modulePath
if (this.isDev) {
modulePath = '../../../process/comment-module-controller.js'
} else {
modulePath = commentControllerRelativePath
} }
this.commentScraper.scrape_next_page_youtube_comments(this.id).then((response) => {
if (response === null) { this.commentProcess = fork(path.join(__dirname, modulePath), ['args'], {
stdio: ['pipe', 'pipe', 'pipe', 'ipc']
})
this.commentProcess.on('message', (msg) => {
if (msg.error === null) {
const commentJSON = JSON.parse(msg.comments)
if (commentJSON === null) {
this.showToast({ this.showToast({
message: this.$t('Comments.No more comments available'), message: this.$t('Comments.No more comments available'),
time: 7000, time: 7000,
@ -140,10 +168,9 @@ export default Vue.extend({
} }
}) })
this.isLoading = false this.isLoading = false
return } else {
} // console.log(msg.comments)
console.log(response) const commentData = commentJSON.map((comment) => {
const commentData = response.map((comment) => {
comment.showReplies = false comment.showReplies = false
comment.dataType = 'local' comment.dataType = 'local'
this.toLocalePublicationString({ this.toLocalePublicationString({
@ -169,18 +196,23 @@ export default Vue.extend({
}) })
return comment return comment
}) })
if (this.sortingChanged) {
this.commentData = []
this.sortingChanged = false
}
this.commentData = this.commentData.concat(commentData) this.commentData = this.commentData.concat(commentData)
this.isLoading = false this.isLoading = false
this.showComments = true this.showComments = true
this.nextPageToken = '' this.nextPageToken = ''
}).catch((err) => { }
console.log(err) } else {
console.log(msg.error)
const errorMessage = this.$t('Local API Error (Click to copy)') const errorMessage = this.$t('Local API Error (Click to copy)')
this.showToast({ this.showToast({
message: `${errorMessage}: ${err}`, message: `${errorMessage}: ${msg.error}`,
time: 10000, time: 10000,
action: () => { action: () => {
navigator.clipboard.writeText(err) navigator.clipboard.writeText(msg.error)
} }
}) })
if (this.backendFallback && this.backendPreference === 'local') { if (this.backendFallback && this.backendPreference === 'local') {
@ -191,7 +223,11 @@ export default Vue.extend({
} else { } else {
this.isLoading = false this.isLoading = false
} }
}
}) })
}
this.commentProcess.send({ id: this.id, sortNewest: this.sortNewest })
}, },
getCommentDataInvidious: function () { getCommentDataInvidious: function () {