This commit is contained in:
Tommy Mikkelsen 2022-09-17 22:15:50 +02:00
parent 1309cb301c
commit ea455291b8
5 changed files with 286 additions and 190 deletions

View file

@ -1,5 +1,16 @@
# ![Logo](https://github.com/WebTools-NG/WebTools-NG/blob/master/src/assets/WebTools-48x48.png) WebTools-ng Change log
## V1.1.2 ( Not released yet )
**Note**: In this version, the following is disabled:
* Export to xlsx format ([See #331](https://github.com/WebTools-NG/WebTools-NG/issues/331))
* Photo export
**Changes**:
* [#598 Refactor tvdb rutines](https://github.com/WebTools-NG/WebTools-NG/issues/598) (Internal)
## V1.1.1 ( 20220917 )
**Note**: In this version, the following is disabled:

2
package-lock.json generated
View file

@ -1,6 +1,6 @@
{
"name": "webtools-ng",
"version": "1.1.1",
"version": "1.1.2",
"lockfileVersion": 2,
"requires": true,
"packages": {

View file

@ -1,7 +1,7 @@
{
"name": "webtools-ng",
"productName": "WebTools-NG",
"version": "1.1.1",
"version": "1.1.2",
"description": "WebTools Next Generation 4 Plex",
"author": "dane22 & CPSO",
"license": "MPL-2.0",

View file

@ -11,6 +11,7 @@ import { status } from '../../General/status';
import { time } from '../../General/time';
import { tmdb } from '../../General/tmdb';
import { tvdb } from '../../General/tvdb';
import { title } from 'process';
var path = require("path");
var sanitize = require("sanitize-filename");
@ -1044,6 +1045,216 @@ const etHelper = new class ETHELPER {
}
async addRowToTmp( { data }) {
if ( this.Settings.levelName == 'Find Missing Episodes'){
this.Settings.showInfo = {};
let id, ids, attributename;
await this.getShowOrdering( { "ratingKey": data["ratingKey"] } );
if ( this.Settings.showInfo["showOrdering"] == "tmdbAiring" ){
console.log('Ged 66-3 tmdb airing')
// Special level, so we need to get info from tmdb
log.info(`[ethelper.js] (addRowToTmp) - Level "Find Missing Episodes" selected, so we must contact tmdb`);
ids = JSONPath({ path: "$.Guid[?(@.id.startsWith('tmdb'))].id", json: data });
if ( ids.length != 1){
this.Settings.showInfo["Link (Cloud)"] = "**** ERROR ****";
log.error(`[ethelper.js] (addRowToTmp) - tmdb guid problem for ${JSONPath({ path: "$.title", json: data })}`);
} else {
id = String(JSONPath({ path: "$.Guid[?(@.id.startsWith('tmdb'))].id", json: data })).substring(7,);
if ( id ){
this.Settings.showInfo["Link (Cloud)"] = `https://www.themoviedb.org/tv/${id}`;
const TMDBInfo = await tmdb.getTMDBShowInfo({tmdbId: id, title: JSONPath({ path: "$.title", json: data })});
for( attributename in TMDBInfo){
this.Settings.showInfo[attributename] = TMDBInfo[attributename];
}
} else {
const title = JSONPath({ path: "$.title", json: data });
log.error(`[ethelper.js] (addRowToTmp) - No tmdb guid found for ${title}`);
}
}
this.Settings.showInfo["showOrdering"] = "TMDB Airing";
this.Settings.showInfo["Status"] = this.Settings.showInfo["TMDBStatus"];
} else {
console.log('Ged 66-3-2 use tvdb')
// Special level, so we need to get info from tvdb
log.info(`[ethelper.js] (addRowToTmp) - Level "Find Missing Episodes" selected, so we must contact tvdb`);
ids = JSONPath({ path: "$.Guid[?(@.id.startsWith('tvdb'))].id", json: data });
if ( ids.length != 1){
this.Settings.showInfo["Link (Cloud)"] = "**** ERROR ****";
log.error(`[ethelper.js] (addRowToTmp) - tvdb guid problem for ${JSONPath({ path: "$.title", json: data })}`);
} else {
let order;
switch ( this.Settings.showInfo["showOrdering"] ) {
case "aired":
log.info(`[ethelper.js] (addRowToTmp) - tvdb aired selected for the show named ${title}`);
order = 'official';
this.Settings.showInfo["showOrdering"] = "TVDB Airing";
break;
case "dvd":
log.info(`[ethelper.js] (addRowToTmp) - tvdb dvd selected for the show named ${title}`);
order = 'dvd';
this.Settings.showInfo["showOrdering"] = "TVDB DVD";
break;
case "absolute":
log.info(`[ethelper.js] (addRowToTmp) - tvdb absolute selected for the show named ${title}`);
order = 'absolute';
this.Settings.showInfo["showOrdering"] = "TVDB Absolute";
break;
}
id = String(JSONPath({ path: "$.Guid[?(@.id.startsWith('tvdb'))].id", json: data })).substring(7,);
// Get TVDB Access Token
if (!this.Settings.tvdbBearer){
this.Settings.tvdbBearer = await tvdb.login();
}
if ( id ){
const showInfo = await tvdb.getTVDBShow( {tvdbId: id, bearer: this.Settings.tvdbBearer, title: JSONPath({ path: "$.title", json: data }), order: order} );
for( attributename in showInfo){
this.Settings.showInfo[attributename] = showInfo[attributename];
}
} else {
const title = JSONPath({ path: "$.title", json: data });
log.error(`[ethelper.js] (addRowToTmp) - No tmdb guid found for ${title}`);
}
}
}
}
this.Settings.currentItem +=1;
status.updateStatusMsg( status.RevMsgType.Items, i18n.t('Common.Status.Msg.ProcessItem_0_1', {count: this.Settings.count, total: this.Settings.endItem}));
log.debug(`[ethelper.js] (addRowToTmp) Start addRowToTmp item ${this.Settings.currentItem} (Switch to Silly log to see contents)`)
log.silly(`[ethelper.js] (addRowToTmp) Data is: ${JSON.stringify(data)}`)
let name, key, type, subType, subKey, doPostProc;
let date, year, month, day, hours, minutes, seconds;
let val, array, i, valArray, valArrayVal
let str = ''
let textSep = wtconfig.get('ET.TextQualifierCSV', '"');
if ( textSep === ' ')
{
textSep = '';
}
try
{
for (var x=0; x<this.Settings.fields.length; x++) {
status.updateStatusMsg( status.RevMsgType.Items, i18n.t('Common.Status.Msg.ProcessItem_0_1', {count: this.Settings.count, total: this.Settings.endItem}));
var fieldDef = JSONPath({path: '$.fields.' + this.Settings.fields[x], json: defFields})[0];
name = this.Settings.fields[x];
key = fieldDef["key"];
type = fieldDef["type"];
subType = fieldDef["subtype"];
subKey = fieldDef["subkey"];
doPostProc = fieldDef["postProcess"];
switch(type) {
case "string":
val = String(JSONPath({path: key, json: data})[0]);
// Make N/A if not found
if (!val)
{
val = wtconfig.get('ET.NotAvail', 'N/A');
}
val = etHelper.isEmpty( { "val": val } );
break;
case "array":
array = JSONPath({path: key, json: data});
if (array === undefined || array.length == 0) {
val = wtconfig.get('ET.NotAvail', 'N/A');
}
else
{
valArray = []
for (i=0; i<array.length; i++) {
switch(String(subType)) {
case "string":
valArrayVal = String(JSONPath({path: String(subKey), json: array[i]}));
// Make N/A if not found
valArrayVal = this.isEmpty( { val: valArrayVal });
break;
case "time":
valArrayVal = JSONPath({path: String(subKey), json: array[i]});
// Make N/A if not found
if (valArrayVal == null || valArrayVal == "")
{
valArrayVal = wtconfig.get('ET.NotAvail', 'N/A')
}
else
{
const total = valArrayVal.length
for (let i=0; i<total; i++) {
valArrayVal = await time.convertMsToTime(valArrayVal);
}
}
break;
default:
log.error('[ethelper.js] (addRowToTmp) NO ARRAY HIT (addRowToSheet-array)')
}
valArray.push(valArrayVal)
}
val = valArray.join(wtconfig.get('ET.ArraySep', ' * '));
}
break;
case "array-count":
val = JSONPath({path: String(key), json: data}).length;
break;
case "int":
val = JSONPath({path: String(key), json: data})[0];
break;
case "time":
val = JSONPath({path: key, json: data});
if ( typeof val !== 'undefined' && val && val != '')
{
val = await time.convertMsToTime(val);
}
else
{
val = wtconfig.get('ET.NotAvail', 'N/A')
}
break;
case "datetime":
val = JSONPath({path: key, json: data});
if ( typeof val !== 'undefined' && val && val != '')
{
// Create a new JavaScript Date object based on the timestamp
// multiplied by 1000 so that the argument is in milliseconds, not seconds.
date = new Date(val * 1000);
year = date.getFullYear().toString();
month = ('0' + date.getMonth().toString()).substr(-2);
day = ('0' + date.getDate().toString()).substr(-2);
hours = date.getHours();
minutes = "0" + date.getMinutes();
seconds = "0" + date.getSeconds();
// Will display time in 10:30:23 format
val = year+'-'+month+'-'+day+' '+hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
}
else
{
val = wtconfig.get('ET.NotAvail', 'N/A')
}
break;
}
if ( doPostProc )
{
const title = JSONPath({path: String('$.title'), json: data})[0];
log.debug(`[ethelper.js] (addRowToTmp doPostProc) - Name is: ${name} - Title is: ${title} - Val is: ${val}`)
val = await this.postProcess( {name: name, val: val, title: title, data: data} );
}
// Here we add qualifier, if not a number
if (!['array-count', 'int'].includes(type))
{
val = setQualifier( {str: val} );
}
str += val + etHelper.intSep;
}
}
catch (error)
{
log.error(`[ethelper.js] (addRowToTmp) - We had an exception as ${error}`);
log.error(`[ethelper.js] (addRowToTmp) - Fields are name: ${name}, key: ${key}, type: ${type}, subType: ${subType}, subKey: ${subKey}`);
}
// Remove last internal separator
str = str.substring(0,str.length-etHelper.intSep.length);
str = str.replaceAll(this.intSep, wtconfig.get("ET.ColumnSep", '|'));
status.updateStatusMsg( status.RevMsgType.TimeElapsed, await time.getTimeElapsed());
log.debug(`etHelper (addRowToTmp) returned: ${JSON.stringify(str)}`);
return str;
}
async DELMEaddRowToTmp( { data }) {
if ( this.Settings.levelName == 'Find Missing Episodes'){
this.Settings.showInfo = {};
let id, ids, attributename;
@ -1086,7 +1297,8 @@ const etHelper = new class ETHELPER {
this.Settings.tvdbBearer = await tvdb.login();
}
if ( id ){
const showInfo = await tvdb.getTVDBShowAired( {tvdbId: id, bearer: this.Settings.tvdbBearer, title: JSONPath({ path: "$.title", json: data })} );
//const showInfo = await tvdb.getTVDBShowAired( {tvdbId: id, bearer: this.Settings.tvdbBearer, title: JSONPath({ path: "$.title", json: data })} );
const showInfo = await tvdb.getTVDBShowAired( {tvdbId: id, bearer: this.Settings.tvdbBearer, title: JSONPath({ path: "$.title", json: data }), order: 'official'} );
for( attributename in showInfo){
this.Settings.showInfo[attributename] = showInfo[attributename];
}

View file

@ -42,197 +42,70 @@ const tvdb = new class TVDB {
return bearer;
}
async getTVDBShowAired( {tvdbId: tvdbId, bearer: bearer, title: title} ){
log.info(`[tvdb.js] (getTVDBShowAired) - Getting tvdb aired info for ${tvdbId}`);
let url = `${this.baseAPIUrl}series/${tvdbId}/episodes/official?page=0`;
let headers = this.headers;
let seasons = {};
headers["Authorization"] = `Bearer ${bearer}`;
let result = {};
await axios({
method: 'get',
url: url,
headers: headers
})
.then((response) => {
log.debug('[tvdb.js] (getTVDBShowAired) - Response from getTVDBShowAired recieved');
result['Link (Cloud)'] = `https://thetvdb.com/series/${JSONPath({ path: "$..slug", json: response.data })[0]}`;
result['Status (Cloud)'] = JSONPath({ path: "$..status.name", json: response.data })[0];
// Sadly, the tvdb doesn't have a count field for seasons and episodes, so we need to count each :-(
let episodes = JSONPath({ path: "$..episodes[*]", json: response.data });
// Gather season/episode info
for ( var idx in episodes ){
const season = JSONPath({ path: "$..seasonNumber", json: episodes[idx] })[0];
if( Object.prototype.hasOwnProperty.call(seasons, season) ){
seasons[season] = seasons[season] + 1;
} else {
seasons[season] = 1;
}
}
// Get Season Count
result['Season Count (Cloud)'] = Object.keys(seasons).length;
// Get episode count
let episodeCount = 0;
Object.entries(seasons).forEach(([key, value]) => {
episodeCount = episodeCount + parseInt(value);
key;
})
result['Episode Count (Cloud)'] = episodeCount;
result['Seasons (Cloud)'] = seasons;
})
.catch(function (error) {
if (error.response) {
log.error(`[tvdb.js] (getTVDBShowAired) - Response error: ${JSON.stringify(error.response.data)}`);
//alert(error.response.data.errors[0].code + " " + error.response.data.errors[0].message);
result['Link (Cloud)'] = '**** ERROR ****';
log.error(`[ethelper.js] (addRowToTmp) - tmdb guid problem for ${title}`);
log.error(`[tmdb.js] (getTVDBShowAired) - Returning: ${JSON.stringify(result)}`);
return result;
} else if (error.request) {
log.error(`[tvdb.js] (getTVDBShowAired) - Request Error: ${error.request}`);
log.error(`[tmdb.js] (getTVDBShowAired) - Returning: ${JSON.stringify(result)}`);
result['Link (Cloud)'] = '**** ERROR ****';
log.error(`[ethelper.js] (addRowToTmp) - tmdb guid problem for ${title}`);
return result;
async getTVDBShow( {tvdbId: tvdbId, bearer: bearer, title: title, order: order} ){
log.info(`[tvdb.js] (getTVDBShowDVD) - Getting tmdb ${order} info for ${tvdbId}`);
let url = `${this.baseAPIUrl}series/${tvdbId}/episodes/${order}?page=0`;
let headers = this.headers;
let seasons = {};
headers["Authorization"] = `Bearer ${bearer}`;
let result = {};
await axios({
method: 'get',
url: url,
headers: headers
})
.then((response) => {
log.debug('[tvdb.js] (getTVDBShow) - Response from getTVDBShow recieved');
result['Link (Cloud)'] = `https://thetvdb.com/series/${JSONPath({ path: "$..slug", json: response.data })[0]}`;
result['Status (Cloud)'] = JSONPath({ path: "$..status.name", json: response.data })[0];
// Sadly, the tvdb doesn't have a count field for seasons and episodes, so we need to count each :-(
let episodes = JSONPath({ path: "$..episodes[*]", json: response.data });
// Gather season/episode info
for ( var idx in episodes ){
const season = JSONPath({ path: "$..seasonNumber", json: episodes[idx] })[0];
if( Object.prototype.hasOwnProperty.call(seasons, season) ){
seasons[season] = seasons[season] + 1;
} else {
log.error(`[tvdb.js] (getTVDBShowAired) - ${error.message}`);
log.error(`[tmdb.js] (getTVDBShowAired) - Returning: ${JSON.stringify(result)}`);
result['Link (Cloud)'] = '**** ERROR ****';
log.error(`[ethelper.js] (addRowToTmp) - tmdb guid problem for ${title}`);
return result;
seasons[season] = 1;
}
}
// Get Season Count
result['Season Count (Cloud)'] = Object.keys(seasons).length;
// Get episode count
let episodeCount = 0;
Object.entries(seasons).forEach(([key, value]) => {
episodeCount = episodeCount + parseInt(value);
key;
})
log.silly(`[tmdb.js] (getTVDBShowAired) - Returning: ${JSON.stringify(result)}`);
return result;
}
result['Episode Count (Cloud)'] = episodeCount;
result['Seasons (Cloud)'] = seasons;
})
.catch(function (error) {
if (error.response) {
log.error(`[tvdb.js] (getTVDBShow) - Response error: ${error.response.data}`);
alert(error.response.data.errors[0].code + " " + error.response.data.errors[0].message);
log.error(`[tmdb.js] (getTVDBShow) - Returning: ${JSON.stringify(result)}`);
result['Link (Cloud)'] = '**** ERROR ****';
log.error(`[tvdb.js] (getTVDBShow) - tmdb guid problem for ${title}`);
return result;
} else if (error.request) {
log.error(`[tvdb.js] (getTVDBShow) - Request Error: ${error.request}`);
log.error(`[tmdb.js] (getTVDBShow) - Returning: ${JSON.stringify(result)}`);
result['Link (Cloud)'] = '**** ERROR ****';
log.error(`[tvdb.js] (getTVDBShow) - tmdb guid problem for ${title}`);
return result;
} else {
log.error(`[tvdb.js] (getTVDBShow) - ${error.message}`);
log.error(`[tmdb.js] (getTVDBShow) - Returning: ${JSON.stringify(result)}`);
result['Link (Cloud)'] = '**** ERROR ****';
log.error(`[tvdb.js] (getTVDBShow) - tmdb guid problem for ${title}`);
return result;
}
})
log.silly(`[tmdb.js] (getTVDBShowDVD) - Returning: ${JSON.stringify(result)}`);
return result;
}
async getTVDBShowDVD( {tvdbId: tvdbId, bearer: bearer, title: title} ){
log.info(`[tvdb.js] (getTVDBShowDVD) - Getting tmdb DVD info for ${tvdbId}`);
let url = `${this.baseAPIUrl}series/${tvdbId}/episodes/dvd?page=0`;
let headers = this.headers;
let seasons = {};
headers["Authorization"] = `Bearer ${bearer}`;
let result = {};
await axios({
method: 'get',
url: url,
headers: headers
})
.then((response) => {
log.debug('[tvdb.js] (getTVDBShowDVD) - Response from getTVDBShowDVD recieved');
result['Link (Cloud)'] = `https://thetvdb.com/series/${JSONPath({ path: "$..slug", json: response.data })[0]}`;
result['Status (Cloud)'] = JSONPath({ path: "$..status.name", json: response.data })[0];
// Sadly, the tvdb doesn't have a count field for seasons and episodes, so we need to count each :-(
let episodes = JSONPath({ path: "$..episodes[*]", json: response.data });
// Gather season/episode info
for ( var idx in episodes ){
const season = JSONPath({ path: "$..seasonNumber", json: episodes[idx] })[0];
if( Object.prototype.hasOwnProperty.call(seasons, season) ){
seasons[season] = seasons[season] + 1;
} else {
seasons[season] = 1;
}
}
// Get Season Count
result['Season Count (Cloud)'] = Object.keys(seasons).length;
// Get episode count
let episodeCount = 0;
Object.entries(seasons).forEach(([key, value]) => {
episodeCount = episodeCount + parseInt(value);
key;
})
result['Episode Count (Cloud)'] = episodeCount;
result['Seasons (Cloud)'] = seasons;
})
.catch(function (error) {
if (error.response) {
log.error(`[tvdb.js] (getTVDBShowDVD) - Response error: ${error.response.data}`);
alert(error.response.data.errors[0].code + " " + error.response.data.errors[0].message);
log.error(`[tmdb.js] (getTVDBShowDVD) - Returning: ${JSON.stringify(result)}`);
result['Link (Cloud)'] = '**** ERROR ****';
log.error(`[ethelper.js] (addRowToTmp) - tmdb guid problem for ${title}`);
return result;
} else if (error.request) {
log.error(`[tvdb.js] (getTVDBShowDVD) - Request Error: ${error.request}`);
log.error(`[tmdb.js] (getTVDBShowDVD) - Returning: ${JSON.stringify(result)}`);
result['Link (Cloud)'] = '**** ERROR ****';
log.error(`[ethelper.js] (addRowToTmp) - tmdb guid problem for ${title}`);
return result;
} else {
log.error(`[tvdb.js] (getTVDBShowDVD) - ${error.message}`);
log.error(`[tmdb.js] (getTVDBShowDVD) - Returning: ${JSON.stringify(result)}`);
result['Link (Cloud)'] = '**** ERROR ****';
log.error(`[ethelper.js] (addRowToTmp) - tmdb guid problem for ${title}`);
return result;
}
})
log.silly(`[tmdb.js] (getTVDBShowDVD) - Returning: ${JSON.stringify(result)}`);
return result;
}
async getTVDBShowAbsolute( {tvdbId: tvdbId, bearer: bearer, title: title} ){
log.info(`[tvdb.js] (getTVDBShowAbsolute) - Getting tmdb Absolute info for ${tvdbId}`);
let url = `${this.baseAPIUrl}series/${tvdbId}/episodes/absolute?page=0`;
let headers = this.headers;
let seasons = {};
headers["Authorization"] = `Bearer ${bearer}`;
let result = {};
await axios({
method: 'get',
url: url,
headers: headers
})
.then((response) => {
log.debug('[tvdb.js] (getTVDBShowAbsolute) - Response from getTVDBShowAbsolute recieved');
result['Link (Cloud)'] = `https://thetvdb.com/series/${JSONPath({ path: "$..slug", json: response.data })[0]}`;
result['Status (Cloud)'] = JSONPath({ path: "$..status.name", json: response.data })[0];
// Sadly, the tvdb doesn't have a count field for seasons and episodes, so we need to count each :-(
let episodes = JSONPath({ path: "$..episodes[*]", json: response.data });
// Gather season/episode info
for ( var idx in episodes ){
const season = JSONPath({ path: "$..seasonNumber", json: episodes[idx] })[0];
if( Object.prototype.hasOwnProperty.call(seasons, season) ){
seasons[season] = seasons[season] + 1;
} else {
seasons[season] = 1;
}
}
// Get Season Count
result['Season Count (Cloud)'] = Object.keys(seasons).length;
// Get episode count
let episodeCount = 0;
Object.entries(seasons).forEach(([key, value]) => {
episodeCount = episodeCount + parseInt(value);
key;
})
result['Episode Count (Cloud)'] = episodeCount;
result['Seasons (Cloud)'] = seasons;
})
.catch(function (error) {
if (error.response) {
log.error(`[tvdb.js] (getTVDBShowAbsolute) - Response error: ${error.response.data}`);
alert(error.response.data.errors[0].code + " " + error.response.data.errors[0].message);
log.error(`[tmdb.js] (getTVDBShowAbsolute) - Returning: ${JSON.stringify(result)}`);
result['Link (Cloud)'] = '**** ERROR ****';
log.error(`[ethelper.js] (addRowToTmp) - tmdb guid problem for ${title}`);
return result;
} else if (error.request) {
log.error(`[tvdb.js] (getTVDBShowAbsolute) - Request Error: ${error.request}`);
log.error(`[tmdb.js] (getTVDBShowAbsolute) - Returning: ${JSON.stringify(result)}`);
result['Link (Cloud)'] = '**** ERROR ****';
log.error(`[ethelper.js] (addRowToTmp) - tmdb guid problem for ${title}`);
return result;
} else {
log.error(`[tvdb.js] (getTVDBShowAbsolute) - ${error.message}`);
log.error(`[tmdb.js] (getTVDBShowAbsolute) - Returning: ${JSON.stringify(result)}`);
result['Link (Cloud)'] = '**** ERROR ****';
log.error(`[ethelper.js] (addRowToTmp) - tmdb guid problem for ${title}`);
return result;
}
})
log.silly(`[tmdb.js] (getTVDBShowAbsolute) - Returning: ${JSON.stringify(result)}`);
return result;
}
}
export { tvdb };