diff --git a/backend/app.js b/backend/app.js index 0cdd414..823ea46 100644 --- a/backend/app.js +++ b/backend/app.js @@ -1192,7 +1192,7 @@ async function downloadFileByURL_exec(url, type, options, sessionID = null) { && config.getConfigItem('ytdl_use_twitch_api') && config.getConfigItem('ytdl_twitch_auto_download_chat')) { let vodId = url.split('twitch.tv/videos/')[1]; vodId = vodId.split('?')[0]; - downloadTwitchChatByVODID(vodId, file_name, type, options.user); + twitch_api.downloadTwitchChatByVODID(vodId, file_name, type, options.user); } // renames file if necessary due to bug @@ -1768,42 +1768,6 @@ function removeFileExtension(filename) { return filename_parts.join('.'); } -async function getTwitchChatByFileID(id, type, user_uid, uuid) { - let file_path = null; - - if (user_uid) { - file_path = path.join('users', user_uid, type, id + '.twitch_chat.json'); - } else { - file_path = path.join(type, id + '.twitch_chat.json'); - } - - var chat_file = null; - if (fs.existsSync(file_path)) { - chat_file = fs.readJSONSync(file_path); - } - - return chat_file; -} - -async function downloadTwitchChatByVODID(vodId, id, type, user_uid) { - const twitch_api_key = config_api.getConfigItem('ytdl_twitch_api_key'); - const chat = await twitch_api.getCommentsForVOD(twitch_api_key, vodId); - - // save file if needec params are included - if (id && type) { - let file_path = null; - if (user_uid) { - file_path = path.join('users', user_uid, type, id + '.twitch_chat.json'); - } else { - file_path = path.join(type, id + '.twitch_chat.json'); - } - - if (chat) fs.writeJSONSync(file_path, chat); - } - - return chat; -} - app.use(function(req, res, next) { res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization"); res.header("Access-Control-Allow-Origin", getOrigin()); @@ -2038,7 +2002,7 @@ app.post('/api/getFile', optionalJwt, function (req, res) { } // check if chat exists for twitch videos - if (file['url'].includes('twitch.tv')) file['chat_exists'] = fs.existsSync(file['path'].substring(0, file['path'].length - 4) + '.twitch_chat.json'); + if (file && file['url'].includes('twitch.tv')) file['chat_exists'] = fs.existsSync(file['path'].substring(0, file['path'].length - 4) + '.twitch_chat.json'); if (file) { res.send({ @@ -2109,11 +2073,12 @@ app.post('/api/getFullTwitchChat', optionalJwt, async (req, res) => { var id = req.body.id; var type = req.body.type; var uuid = req.body.uuid; + var sub = req.body.sub; var user_uid = null; if (req.isAuthenticated()) user_uid = req.user.uid; - const chat_file = await getTwitchChatByFileID(id, type, user_uid, uuid); + const chat_file = await twitch_api.getTwitchChatByFileID(id, type, user_uid, uuid, sub); res.send({ chat: chat_file @@ -2125,28 +2090,19 @@ app.post('/api/downloadTwitchChatByVODID', optionalJwt, async (req, res) => { var type = req.body.type; var vodId = req.body.vodId; var uuid = req.body.uuid; + var sub = req.body.sub; var user_uid = null; if (req.isAuthenticated()) user_uid = req.user.uid; // check if file already exists. if so, send that instead - const file_exists_check = await getTwitchChatByFileID(id, type, user_uid, uuid); + const file_exists_check = await twitch_api.getTwitchChatByFileID(id, type, user_uid, uuid, sub); if (file_exists_check) { res.send({chat: file_exists_check}); return; } - const full_chat = await downloadTwitchChatByVODID(vodId); - - let file_path = null; - - if (user_uid) { - file_path = path.join('users', req.user.uid, type, id + '.twitch_chat.json'); - } else { - file_path = path.join(type, id + '.twitch_chat.json'); - } - - if (full_chat) fs.writeJSONSync(file_path, full_chat); + const full_chat = await twitch_api.downloadTwitchChatByVODID(vodId, id, type, user_uid, sub); res.send({ chat: full_chat @@ -2435,9 +2391,15 @@ app.post('/api/getSubscription', optionalJwt, async (req, res) => { var file_obj = new utils.File(id, title, thumbnail, isaudio, duration, url, uploader, size, file, upload_date); parsed_files.push(file_obj); } + } else { + // loop through files for extra processing + for (let i = 0; i < parsed_files.length; i++) { + const file = parsed_files[i]; + // check if chat exists for twitch videos + if (file && file['url'].includes('twitch.tv')) file['chat_exists'] = fs.existsSync(file['path'].substring(0, file['path'].length - 4) + '.twitch_chat.json'); + } } - res.send({ subscription: subscription, files: parsed_files diff --git a/backend/subscriptions.js b/backend/subscriptions.js index 4bd071b..9ab7542 100644 --- a/backend/subscriptions.js +++ b/backend/subscriptions.js @@ -6,7 +6,8 @@ var path = require('path'); var youtubedl = require('youtube-dl'); const config_api = require('./config'); -var utils = require('./utils') +const twitch_api = require('./twitch'); +var utils = require('./utils'); const debugMode = process.env.YTDL_MODE === 'debug'; @@ -418,6 +419,15 @@ function handleOutputJSON(sub, sub_db, output_json, multiUserMode = null, reset_ sub_db.get('videos').push(output_json).write(); } else { db_api.registerFileDB(path.basename(output_json['_filename']), sub.type, multiUserMode, sub); + const url = output_json['webpage_url']; + if (sub.type === 'video' && url.includes('twitch.tv/videos/') && url.split('twitch.tv/videos/').length > 1 + && config_api.getConfigItem('ytdl_use_twitch_api') && config_api.getConfigItem('ytdl_twitch_auto_download_chat')) { + const file_name = path.basename(output_json['_filename']); + const id = file_name.substring(0, file_name.length-4); + let vodId = url.split('twitch.tv/videos/')[1]; + vodId = vodId.split('?')[0]; + twitch_api.downloadTwitchChatByVODID(vodId, id, sub.type, multiUserMode.user, sub); + } } } diff --git a/backend/twitch.js b/backend/twitch.js index fb05fbb..2a231e9 100644 --- a/backend/twitch.js +++ b/backend/twitch.js @@ -1,5 +1,8 @@ var moment = require('moment'); var Axios = require('axios'); +var fs = require('fs-extra') +var path = require('path'); +const config_api = require('./config'); async function getCommentsForVOD(clientID, vodId) { let url = `https://api.twitch.tv/v5/videos/${vodId}/comments?content_offset_seconds=0`, @@ -68,6 +71,58 @@ async function getCommentsForVOD(clientID, vodId) { return comments; } +async function getTwitchChatByFileID(id, type, user_uid, uuid, sub) { + let file_path = null; + + if (user_uid) { + if (sub) { + file_path = path.join('users', user_uid, 'subscriptions', sub.isPlaylist ? 'playlists' : 'channels', sub.name, id + '.twitch_chat.json'); + } else { + file_path = path.join('users', user_uid, type, id + '.twitch_chat.json'); + } + } else { + if (sub) { + file_path = path.join('subscriptions', sub.isPlaylist ? 'playlists' : 'channels', sub.name, id + '.twitch_chat.json'); + } else { + file_path = path.join(type, id + '.twitch_chat.json'); + } + } + + var chat_file = null; + if (fs.existsSync(file_path)) { + chat_file = fs.readJSONSync(file_path); + } + + return chat_file; +} + +async function downloadTwitchChatByVODID(vodId, id, type, user_uid, sub) { + const twitch_api_key = config_api.getConfigItem('ytdl_twitch_api_key'); + const chat = await getCommentsForVOD(twitch_api_key, vodId); + + // save file if needed params are included + let file_path = null; + if (user_uid) { + if (sub) { + file_path = path.join('users', user_uid, 'subscriptions', sub.isPlaylist ? 'playlists' : 'channels', sub.name, id + '.twitch_chat.json'); + } else { + file_path = path.join('users', user_uid, type, id + '.twitch_chat.json'); + } + } else { + if (sub) { + file_path = path.join('subscriptions', sub.isPlaylist ? 'playlists' : 'channels', sub.name, id + '.twitch_chat.json'); + } else { + file_path = path.join(type, id + '.twitch_chat.json'); + } + } + + if (chat) fs.writeJSONSync(file_path, chat); + + return chat; +} + module.exports = { - getCommentsForVOD: getCommentsForVOD + getCommentsForVOD: getCommentsForVOD, + getTwitchChatByFileID: getTwitchChatByFileID, + downloadTwitchChatByVODID: downloadTwitchChatByVODID } \ No newline at end of file diff --git a/src/app/components/twitch-chat/twitch-chat.component.html b/src/app/components/twitch-chat/twitch-chat.component.html index 634cac6..43fbac0 100644 --- a/src/app/components/twitch-chat/twitch-chat.component.html +++ b/src/app/components/twitch-chat/twitch-chat.component.html @@ -1,7 +1,8 @@