2021-11-21 03:17:10 +00:00
|
|
|
// ==UserScript==
|
|
|
|
// @name AnimeBytes Mediainfo Improvements
|
|
|
|
// @author WeebDataHoarder
|
2021-11-25 18:13:36 +00:00
|
|
|
// @version 1.9.1
|
2021-11-21 03:17:10 +00:00
|
|
|
// @downloadURL https://git.gammaspectra.live/WeebDataHoarder/userscripts/raw/branch/master/AnimeBytes/ab-mediainfo.user.js
|
|
|
|
// @updateURL https://git.gammaspectra.live/WeebDataHoarder/userscripts/raw/branch/master/AnimeBytes/ab-mediainfo.user.js
|
|
|
|
// @description AnimeBytes Mediainfo Improvements. Adds several listing and matching releases against mediainfo utilities. MIT license
|
|
|
|
// @match https://animebytes.tv/torrents.php?*id=*
|
|
|
|
// @icon http://animebytes.tv/favicon.ico
|
|
|
|
// @run-at document-end
|
|
|
|
// ==/UserScript==
|
|
|
|
|
|
|
|
function parseMediaInfo(text){
|
|
|
|
let ob = {};
|
|
|
|
let currentKey = null;
|
|
|
|
let currentOb = null;
|
|
|
|
|
|
|
|
try{
|
|
|
|
text.split("\n").forEach((line) => {
|
|
|
|
const cleanLine = line.trim();
|
|
|
|
if(cleanLine === ""){
|
|
|
|
return;
|
|
|
|
}else if(!cleanLine.includes(":")){
|
|
|
|
if(currentOb !== null && Object.keys(currentOb).length === 0){
|
|
|
|
//Nothing added, error, invalid mediainfo
|
|
|
|
throw ("Invalid key " + currentKey);
|
|
|
|
}
|
|
|
|
currentKey = cleanLine.toLowerCase();
|
|
|
|
let listMatch = currentKey.match(/^(?<kind>(video|audio|text))( #)?(?<number>[0-9]*)$/i);
|
|
|
|
currentOb = {};
|
|
|
|
if(listMatch !== null){
|
|
|
|
let k = listMatch.groups.kind;
|
|
|
|
if(!(k in ob)){
|
|
|
|
ob[k] = [];
|
|
|
|
}
|
|
|
|
ob[k].push(currentOb);
|
|
|
|
}else{
|
|
|
|
ob[currentKey] = currentOb;
|
|
|
|
}
|
|
|
|
}else if(currentOb !== null){
|
2021-11-25 17:36:14 +00:00
|
|
|
const matches = cleanLine.match(/^(?<key>((?!\s:).)+)[\s]*:(?<value>.+)$/);
|
2021-11-21 03:17:10 +00:00
|
|
|
if(matches !== null){
|
2021-11-21 14:41:03 +00:00
|
|
|
let key = matches.groups.key.trim().toLowerCase().replace(/[ \/*]/g, "_").replace(/[(),]/g, "");
|
2021-11-21 03:17:10 +00:00
|
|
|
currentOb[key] = matches.groups.value.trim();
|
|
|
|
}else{
|
2021-11-25 17:36:14 +00:00
|
|
|
throw "Invalid entry: " + cleanLine;
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
}else{
|
2021-11-25 17:36:14 +00:00
|
|
|
throw "Invalid state: " + cleanLine;
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}catch (e){
|
|
|
|
console.log(text);
|
|
|
|
console.log(e);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ob;
|
|
|
|
}
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
/**
|
|
|
|
* @param v
|
|
|
|
* @param legacy
|
|
|
|
* @returns String
|
|
|
|
*/
|
2021-11-21 03:17:10 +00:00
|
|
|
function getLineTagEntry(v, legacy){
|
|
|
|
if(typeof v === 'object'){
|
|
|
|
return legacy ? v.legacy : (v.name/* + ("lossless" in v ? " (Lossless)" : "")*/);
|
|
|
|
}
|
|
|
|
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getAudioChannels(a){
|
|
|
|
if(a === 3){
|
|
|
|
return "2.1";
|
|
|
|
}else if(a === 5){
|
|
|
|
return "4.1";
|
|
|
|
}else if(a === 6){
|
|
|
|
return "5.1";
|
|
|
|
}else if(a === 8){
|
|
|
|
return "7.1";
|
|
|
|
}
|
|
|
|
|
|
|
|
return a + ".0";
|
|
|
|
}
|
|
|
|
|
|
|
|
function getComparisonLine(tags){
|
|
|
|
|
|
|
|
let entries = [];
|
|
|
|
entries.push(getLineTagEntry(tags.source, true));
|
|
|
|
entries.push(getLineTagEntry(tags.container, true) + ("region" in tags ? " (" + tags.region + ")" : ""));
|
|
|
|
|
|
|
|
if("aspectRatio" in tags){
|
|
|
|
entries.push(tags.aspectRatio);
|
|
|
|
}
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
if("videoCodec" in tags && !(
|
|
|
|
getLineTagEntry(tags.source, true).match(/^DVD[59]$/) !== null
|
|
|
|
)){
|
2021-11-21 03:17:10 +00:00
|
|
|
entries.push(getLineTagEntry(tags.videoCodec, true));
|
|
|
|
}
|
|
|
|
entries.push(tags.resolution);
|
|
|
|
|
|
|
|
entries.push(getLineTagEntry(tags.audioCodec, true) + " " + getAudioChannels(tags.audioChannels));
|
|
|
|
if(tags.audioCount > 1){
|
|
|
|
entries.push("Dual Audio");
|
|
|
|
}
|
|
|
|
entries.push(("subtitleType" in tags ? getLineTagEntry(tags.subtitleType, true) : "RAW") + ("group" in tags ? " (" + tags.group + ")" : ""));
|
|
|
|
return entries.join(" | ");
|
|
|
|
}
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
function getEntryLine(tags, infoCount, warningCount, dangerCount){
|
|
|
|
// Source + container + remux | Codec / Resolution / HDR | Audio + Dual + commentary | Text | OtherTags | icons
|
|
|
|
let entries = {
|
|
|
|
source: [],
|
|
|
|
video: [],
|
|
|
|
audio: [],
|
|
|
|
text: [],
|
|
|
|
other: [],
|
|
|
|
icons: []
|
|
|
|
};
|
|
|
|
entries.source.push(getLineTagEntry(tags.source, false) + ("sourceName" in tags ? " (" + tags.sourceName + ")" : ""));
|
|
|
|
entries.source.push(getLineTagEntry(tags.container, false) + ("region" in tags ? " (" + tags.region + ")" : ""));
|
|
|
|
|
|
|
|
entries.video.push(getLineTagEntry(tags.videoCodec, false) + ("videoEncoder" in tags ? " (" + tags.videoEncoder + ("videoCRF" in tags ? " " + tags.videoCRF : "") + ")" : ""));
|
|
|
|
entries.video.push(tags.resolution + ("aspectRatio" in tags ? " " + tags.aspectRatio : "") /* + ("videoFrameRate" in tags ? " @ " + tags.videoFrameRate : "")*/);
|
2021-11-21 03:17:10 +00:00
|
|
|
if("videoHDR" in tags){
|
2021-11-25 18:07:42 +00:00
|
|
|
entries.video.push(getLineTagEntry(tags.videoHDR, false));
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
entries.audio.push(getLineTagEntry(tags.audioCodec, false) + " " + getAudioChannels(tags.audioChannels));
|
2021-11-21 03:17:10 +00:00
|
|
|
if(tags.audioCount > 1){
|
2021-11-25 18:07:42 +00:00
|
|
|
entries.audio.push("Dual");
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
|
2021-11-21 13:15:27 +00:00
|
|
|
if("audioCommentary" in tags && tags.audioCommentary){
|
2021-11-25 18:07:42 +00:00
|
|
|
entries.audio.push("Commentary");
|
2021-11-21 13:15:27 +00:00
|
|
|
}
|
|
|
|
|
2021-11-21 14:41:03 +00:00
|
|
|
if("remux" in tags){
|
|
|
|
if(tags.remux === true){
|
2021-11-25 18:07:42 +00:00
|
|
|
entries.source.push("REMUX");
|
2021-11-21 14:41:03 +00:00
|
|
|
}else if(tags.remux === "probably"){
|
2021-11-25 18:07:42 +00:00
|
|
|
entries.source.push("REMUX*");
|
2021-11-21 14:41:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-21 13:15:27 +00:00
|
|
|
if(tags.remastered){
|
|
|
|
let img = document.createElement("img");
|
|
|
|
img.src = "/static/common/rmstr.png";
|
|
|
|
img.alt = "Remastered";
|
|
|
|
img.title = "This torrent is from a remastered source!";
|
2021-11-25 18:07:42 +00:00
|
|
|
entries.other.push(img);
|
2021-11-21 13:15:27 +00:00
|
|
|
}
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
entries.text.push(("subtitleCodec" in tags ? tags.subtitleCodec + " " : "") + ("subtitleType" in tags ? getLineTagEntry(tags.subtitleType, false) : "RAW") + ("group" in tags ? " (" + tags.group + ")" : ""));
|
2021-11-21 03:17:10 +00:00
|
|
|
|
2021-11-21 13:15:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
if(tags.freeleech){
|
|
|
|
let img = document.createElement("img");
|
|
|
|
img.src = "/static/common/flicon.png";
|
|
|
|
img.alt = "Freeleech!";
|
|
|
|
img.title = "This torrent is freeleech. Remember to seed!";
|
2021-11-25 18:07:42 +00:00
|
|
|
entries.other.push(img);
|
|
|
|
}
|
|
|
|
|
|
|
|
if("chapters" in tags){
|
|
|
|
entries.other.push(tags.chapters === "ordered" ? "Ordered Chapters" : "Chapters");
|
|
|
|
}
|
|
|
|
|
|
|
|
if(tags.snatched){
|
|
|
|
entries.other.push("Snatched");
|
2021-11-21 13:15:27 +00:00
|
|
|
}
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
if(infoCount > 0 || warningCount > 0 || dangerCount > 0){
|
|
|
|
|
|
|
|
let span = document.createElement("span");
|
|
|
|
|
|
|
|
for(let i = 0; i < infoCount; ++i){
|
|
|
|
span.append("★");
|
|
|
|
}
|
|
|
|
for(let i = 0; i < warningCount; ++i){
|
|
|
|
let icon = document.createElement("img");
|
|
|
|
icon.src = "/static/common/symbols/warned.png";
|
|
|
|
span.append(icon);
|
|
|
|
}
|
|
|
|
for(let i = 0; i < dangerCount; ++i){
|
|
|
|
let icon = document.createElement("img");
|
|
|
|
icon.src = "/static/common/symbols/disabled.png";
|
|
|
|
span.append(icon);
|
|
|
|
}
|
|
|
|
entries.icons.unshift(span);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-21 13:15:27 +00:00
|
|
|
return entries;
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const allowedVideoTypes = [
|
|
|
|
"Movie",
|
|
|
|
"OVA",
|
|
|
|
"ONA",
|
|
|
|
"TV Series",
|
|
|
|
"TV Special",
|
|
|
|
"DVD Special",
|
|
|
|
"BD Special"
|
|
|
|
];
|
|
|
|
|
|
|
|
const knownSources = [
|
|
|
|
"TV",
|
|
|
|
"DVD",
|
|
|
|
"DVD5",
|
|
|
|
"DVD9",
|
|
|
|
"Blu-ray",
|
|
|
|
"UHD Blu-ray",
|
|
|
|
"HD DVD",
|
|
|
|
"VHS",
|
|
|
|
"LD",
|
|
|
|
"Web"
|
|
|
|
];
|
|
|
|
|
|
|
|
const knownContainers = [
|
|
|
|
"AVI",
|
|
|
|
"MKV",
|
|
|
|
"MP4",
|
|
|
|
"OGM",
|
|
|
|
"WMV",
|
|
|
|
"MPG",
|
|
|
|
"ISO",
|
|
|
|
"VOB",
|
|
|
|
"VOB IFO",
|
|
|
|
"TS",
|
|
|
|
"M2TS",
|
|
|
|
"FLV",
|
|
|
|
"RMVB"
|
|
|
|
];
|
|
|
|
|
|
|
|
const knownVideoCodecs = [
|
|
|
|
"h264",
|
|
|
|
"h264 10-bit",
|
|
|
|
"h265",
|
|
|
|
"h265 10-bit",
|
|
|
|
"XviD",
|
|
|
|
"DivX",
|
|
|
|
"WMV",
|
|
|
|
"MPEG-1/2",
|
|
|
|
"VC-1",
|
|
|
|
"MPEG-TS",
|
|
|
|
"DVD5",
|
|
|
|
"DVD9",
|
|
|
|
"RealVideo",
|
|
|
|
"VP6",
|
|
|
|
"VP9",
|
|
|
|
"AV1"
|
|
|
|
];
|
|
|
|
|
|
|
|
const knownAudioCodecs = [
|
|
|
|
"MP3",
|
|
|
|
"Vorbis",
|
|
|
|
"Opus",
|
|
|
|
"AAC",
|
|
|
|
"AC3",
|
|
|
|
"TrueHD",
|
|
|
|
"DTS",
|
|
|
|
"DTS-ES",
|
|
|
|
"FLAC",
|
|
|
|
"PCM",
|
|
|
|
"WMA",
|
|
|
|
"MP2",
|
|
|
|
"WAV",
|
|
|
|
"DTS-HD",
|
|
|
|
"DTS-HD MA",
|
|
|
|
"RealAudio"
|
|
|
|
];
|
|
|
|
|
|
|
|
const audioCodecs = [
|
2021-11-21 17:35:27 +00:00
|
|
|
{
|
|
|
|
name: "AAC-LC",
|
|
|
|
match: {
|
|
|
|
codec_id: /^A_AAC/,
|
|
|
|
format_profile: "LC"
|
|
|
|
},
|
|
|
|
legacy: "AAC"
|
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
{
|
|
|
|
name: "HE-AAC",
|
|
|
|
match: {
|
|
|
|
codec_id: /^A_AAC/,
|
|
|
|
format_profile: /HE-AAC/
|
|
|
|
},
|
|
|
|
legacy: "AAC"
|
|
|
|
},
|
2021-11-21 17:35:27 +00:00
|
|
|
{
|
|
|
|
name: "AAC-LC",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_AAC-2"
|
|
|
|
},
|
|
|
|
legacy: "AAC"
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "AAC-Main",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_AAC-1"
|
|
|
|
},
|
|
|
|
legacy: "AAC"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "AAC-Main",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_AAC",
|
|
|
|
format_profile: "Main"
|
|
|
|
},
|
|
|
|
legacy: "AAC"
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "AC3",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_AC3"
|
|
|
|
},
|
|
|
|
legacy: "AC3"
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "Opus",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_OPUS"
|
|
|
|
},
|
|
|
|
legacy: "Opus"
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "Vorbis",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_VORBIS"
|
|
|
|
},
|
|
|
|
legacy: "Vorbis"
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "WAV",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_WAVPACK4"
|
|
|
|
},
|
|
|
|
legacy: "WAV"
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "MP2",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_MPEG/L2"
|
|
|
|
},
|
|
|
|
legacy: "MP2"
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "MP3",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_MPEG/L3"
|
|
|
|
},
|
|
|
|
legacy: "MP3"
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "FLAC",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_FLAC"
|
|
|
|
},
|
|
|
|
legacy: "FLAC",
|
|
|
|
lossless: true
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "PCM",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_PCM/INT/LIT"
|
|
|
|
},
|
|
|
|
legacy: "PCM",
|
|
|
|
lossless: true
|
|
|
|
},
|
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
{
|
|
|
|
name: "E-AC3",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_EAC3",
|
|
|
|
number_of_dynamic_objects: null
|
|
|
|
},
|
|
|
|
legacy: "AC3"
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "E-AC3 Atmos",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_EAC3",
|
|
|
|
number_of_dynamic_objects: /^[0-9]+$/
|
|
|
|
},
|
|
|
|
legacy: "AC3"
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "TrueHD Atmos",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_TRUEHD",
|
|
|
|
number_of_dynamic_objects: /^[0-9]+$/
|
|
|
|
},
|
|
|
|
legacy: "TrueHD",
|
|
|
|
lossless: true
|
|
|
|
},
|
2021-11-21 17:35:27 +00:00
|
|
|
{
|
|
|
|
name: "TrueHD",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_TRUEHD",
|
|
|
|
number_of_dynamic_objects: null
|
|
|
|
},
|
|
|
|
legacy: "TrueHD",
|
|
|
|
lossless: true
|
|
|
|
},
|
2021-11-21 13:15:27 +00:00
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
{
|
|
|
|
name: "DTS:X MA",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_DTS",
|
|
|
|
format: "DTS XLL X",
|
|
|
|
channels_original: "Object Based"
|
|
|
|
},
|
|
|
|
legacy: "DTS-HD MA",
|
|
|
|
lossless: true
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "DTS-HD MA",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_DTS",
|
|
|
|
format: "DTS XLL",
|
|
|
|
channels_original: null,
|
|
|
|
},
|
|
|
|
legacy: "DTS-HD MA",
|
|
|
|
lossless: true
|
2021-11-21 13:15:27 +00:00
|
|
|
},
|
2021-11-21 17:35:27 +00:00
|
|
|
{
|
|
|
|
name: "DTS-HD",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_DTS",
|
|
|
|
format: "DTS XBR",
|
|
|
|
},
|
|
|
|
legacy: "DTS-HD"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "DTS",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_DTS",
|
|
|
|
format: "DTS",
|
|
|
|
format_profile: null,
|
|
|
|
},
|
|
|
|
legacy: "DTS"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "DTS-ES",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_DTS",
|
|
|
|
format: "DTS ES",
|
|
|
|
},
|
|
|
|
legacy: "DTS-ES"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "DTS-HD MA",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_DTS",
|
|
|
|
format_profile: /^MA/,
|
|
|
|
channels_original: null,
|
|
|
|
},
|
|
|
|
legacy: "DTS-HD MA",
|
|
|
|
lossless: true
|
|
|
|
},
|
|
|
|
{ //Old way of identifying
|
|
|
|
name: "DTS-ES",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_DTS",
|
|
|
|
format_profile: /^ES/,
|
|
|
|
},
|
|
|
|
legacy: "DTS-ES"
|
|
|
|
},
|
2021-11-21 13:15:27 +00:00
|
|
|
{ //Old way of identifying
|
|
|
|
name: "DTS-HD MA",
|
|
|
|
match: {
|
|
|
|
codec_id: "A_DTS",
|
|
|
|
format_profile: "MA / Core",
|
|
|
|
channels_original: null,
|
|
|
|
},
|
|
|
|
legacy: "DTS-HD MA",
|
|
|
|
lossless: true
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
];
|
|
|
|
|
|
|
|
const videoCodecs = [
|
2021-11-22 09:10:25 +00:00
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
{
|
2021-11-22 09:10:25 +00:00
|
|
|
name: "MPEG-1",
|
2021-11-21 03:17:10 +00:00
|
|
|
match: {
|
2021-11-22 09:10:25 +00:00
|
|
|
codec_id: "V_MPEG1",
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
legacy: "MPEG-1/2"
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
|
|
|
{
|
2021-11-22 09:10:25 +00:00
|
|
|
name: "MPEG-2",
|
2021-11-21 03:17:10 +00:00
|
|
|
match: {
|
2021-11-22 09:10:25 +00:00
|
|
|
codec_id: "V_MPEG2",
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
legacy: "MPEG-1/2"
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-25 18:07:42 +00:00
|
|
|
{
|
|
|
|
name: "MPEG-$version",
|
|
|
|
match: {
|
|
|
|
format: "MPEG Video",
|
|
|
|
format_version: /^Version (?<version>[12])$/,
|
|
|
|
},
|
|
|
|
legacy: "MPEG-1/2"
|
|
|
|
},
|
2021-11-21 03:17:10 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
name: "h264",
|
|
|
|
match: {
|
|
|
|
codec_id: "V_MPEG4/ISO/AVC",
|
|
|
|
bit_depth: "8 bits",
|
|
|
|
chroma_subsampling: /^4:2:0/
|
|
|
|
},
|
|
|
|
legacy: "h264"
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2021-11-22 09:10:25 +00:00
|
|
|
name: "h264 $bitDepth-bit $chroma",
|
2021-11-21 03:17:10 +00:00
|
|
|
match: {
|
2021-11-22 09:10:25 +00:00
|
|
|
codec_id: "V_MPEG4/ISO/AVC",
|
|
|
|
bit_depth: /^(?<bitDepth>10) bits/,
|
|
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
legacy: "h264 $bitDepth-bit"
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2021-11-22 09:10:25 +00:00
|
|
|
name: "VC-1 $codec",
|
2021-11-21 03:17:10 +00:00
|
|
|
match: {
|
2021-11-22 09:10:25 +00:00
|
|
|
codec_id: /^V_MS\/VFW\/FOURCC \/ (?<codec>WMV3|WMVA|WVC1)/,
|
|
|
|
bit_depth: "8 bits"
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
legacy: "VC-1"
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2021-11-22 09:10:25 +00:00
|
|
|
name: "VP9 $chroma",
|
2021-11-21 03:17:10 +00:00
|
|
|
match: {
|
2021-11-22 09:10:25 +00:00
|
|
|
codec_id: "V_VP9",
|
|
|
|
bit_depth: "8 bits",
|
|
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
legacy: "VP9"
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
{
|
2021-11-22 09:10:25 +00:00
|
|
|
name: "VP9 $bitDepth-bit $chroma",
|
2021-11-21 03:17:10 +00:00
|
|
|
match: {
|
2021-11-22 09:10:25 +00:00
|
|
|
codec_id: "V_VP9",
|
|
|
|
bit_depth: /^(?<bitDepth>10|12) bits/,
|
|
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
legacy: "VP9"
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
{
|
2021-11-22 09:10:25 +00:00
|
|
|
name: "AV1 $chroma",
|
2021-11-21 03:17:10 +00:00
|
|
|
match: {
|
2021-11-22 09:10:25 +00:00
|
|
|
codec_id: "V_AV1",
|
|
|
|
bit_depth: "8 bits",
|
|
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
legacy: "AV1"
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
{
|
2021-11-22 09:10:25 +00:00
|
|
|
name: "AV1 $bitDepth-bit $chroma",
|
2021-11-21 03:17:10 +00:00
|
|
|
match: {
|
2021-11-22 09:10:25 +00:00
|
|
|
codec_id: "V_AV1",
|
|
|
|
bit_depth: /^(?<bitDepth>10|12) bits/,
|
|
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
legacy: "AV1"
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
{
|
2021-11-22 09:10:25 +00:00
|
|
|
name: "h265",
|
2021-11-21 03:17:10 +00:00
|
|
|
match: {
|
|
|
|
codec_id: "V_MPEGH/ISO/HEVC",
|
2021-11-22 09:10:25 +00:00
|
|
|
bit_depth: "8 bits",
|
2021-11-21 03:17:10 +00:00
|
|
|
chroma_subsampling: /^4:2:0/
|
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
legacy: "h265"
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
{
|
2021-11-22 09:10:25 +00:00
|
|
|
name: "h265 $bitDepth-bit $chroma",
|
2021-11-21 03:17:10 +00:00
|
|
|
match: {
|
|
|
|
codec_id: "V_MPEGH/ISO/HEVC",
|
2021-11-22 09:10:25 +00:00
|
|
|
bit_depth: /^(?<bitDepth>10|12) bits/,
|
|
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
2021-11-22 09:10:25 +00:00
|
|
|
legacy: "h265 $bitDepth-bit"
|
2021-11-21 03:17:10 +00:00
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const torrentType = document.querySelector("a.scaledImg > img").getAttribute("title");
|
2021-11-25 18:07:42 +00:00
|
|
|
const torrentTableColspan = 6;
|
2021-11-21 03:17:10 +00:00
|
|
|
if(allowedVideoTypes.indexOf(torrentType.replace("Live Action ", "")) !== -1){
|
2021-11-25 18:07:42 +00:00
|
|
|
|
|
|
|
//Make page wider
|
|
|
|
let contentStyle = document.getElementById("content").style;
|
|
|
|
contentStyle["max-width"] = "1400px";
|
|
|
|
contentStyle["width"] = "calc(100% - 50px)";
|
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
let episodeCount = 0;
|
|
|
|
document.querySelectorAll("ul.stats > li").forEach((item) => {
|
|
|
|
let strongItem = item.querySelector("strong");
|
|
|
|
if(strongItem !== null && strongItem.textContent === "Episodes:"){
|
|
|
|
episodeCount = parseInt(item.querySelector("a").textContent);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if(episodeCount === 0 && (torrentType === "Movie")){
|
|
|
|
episodeCount = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
let torrentListing = [];
|
|
|
|
|
|
|
|
document.querySelectorAll(".group_torrent").forEach((item) => {
|
|
|
|
const linkSection = item.querySelector("td");
|
|
|
|
const downloadLink = item.querySelector("a[title^='Download']");
|
|
|
|
const [torrentEntry] = Array.from(linkSection.querySelectorAll("a")).slice(-1);
|
|
|
|
|
|
|
|
const torrentId = parseInt(downloadLink.getAttribute("href").match(/\/torrent\/(?<torrent_id>[0-9]+)\/download/).groups.torrent_id);
|
|
|
|
|
|
|
|
|
|
|
|
let tags = {
|
|
|
|
audioCount: 1,
|
2021-11-21 13:15:27 +00:00
|
|
|
freeleech: torrentEntry.querySelector("img[alt^='Freeleech!']") !== null,
|
|
|
|
remastered: torrentEntry.querySelector("img[alt^='Remastered']") !== null,
|
2021-11-21 03:17:10 +00:00
|
|
|
snatched: torrentEntry.textContent.match(/ - Snatched/) !== null
|
|
|
|
};
|
|
|
|
torrentEntry.textContent.replace("»", "").replace(" - Snatched", "").split(" | ").forEach((t) => {
|
|
|
|
let tagEntry = t.trim();
|
|
|
|
|
|
|
|
if(tagEntry === ""){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let match = null;
|
|
|
|
|
|
|
|
if(!("source" in tags) && knownSources.indexOf(tagEntry) !== -1){
|
|
|
|
tags.source = tagEntry;
|
|
|
|
}else if(!("container" in tags) && knownContainers.some((i) => tagEntry.startsWith(i))){
|
|
|
|
if((match = tagEntry.match(/^(?<container>[^(]+) \((?<region>[^)]+)\)$/)) !== null){
|
|
|
|
tags.container = match.groups.container;
|
|
|
|
tags.region = match.groups.region;
|
|
|
|
}else{
|
|
|
|
tags.container = tagEntry;
|
|
|
|
}
|
|
|
|
}else if(!("videoCodec" in tags) && knownVideoCodecs.some((i) => tagEntry.startsWith(i))){
|
|
|
|
tags.videoCodec = tagEntry;
|
|
|
|
}else if(!("audioCodec" in tags) && knownAudioCodecs.some((i) => tagEntry.startsWith(i))){
|
|
|
|
match = tagEntry.match(/^(?<codec>.+) (?<channels>[0-9.]+)$/)
|
|
|
|
tags.audioCodec = match.groups.codec;
|
|
|
|
tags.audioChannels = match.groups.channels.split(".").reduce((p, c) => parseInt(p) + parseInt(c));
|
|
|
|
}else if(tagEntry.match(/^[0-9]+:[0-9]+$/) !== null){
|
|
|
|
tags.aspectRatio = tagEntry;
|
|
|
|
}else if(tagEntry.match(/^[0-9]+x[0-9]+$/) !== null || tagEntry.match(/^(720p|1080p|1080i|4K)$/) !== null){
|
|
|
|
tags.resolution = tagEntry;
|
|
|
|
}else if(tagEntry === "Dual Audio"){
|
|
|
|
tags.audioCount = 2;
|
|
|
|
}else if((match = tagEntry.match(/^(?<kind>(RAW|Hardsubs|Softsubs))( \()?(?<group>[^)]*)(\))?$/)) !== null){
|
|
|
|
if(match.groups.kind !== "RAW"){
|
|
|
|
tags.subtitleType = match.groups.kind;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(match.groups.group !== ""){
|
|
|
|
tags.group = match.groups.group;
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
//console.log(tagEntry);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
let torrent = {
|
|
|
|
id: torrentId,
|
|
|
|
tags: tags,
|
|
|
|
elements: {
|
|
|
|
item: item,
|
|
|
|
entry: torrentEntry,
|
|
|
|
link: downloadLink,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const dataSection = document.getElementById("torrent_" + torrentId);
|
|
|
|
if(dataSection !== null){
|
2021-11-25 18:07:42 +00:00
|
|
|
torrent.elements.data = dataSection;
|
2021-11-21 03:17:10 +00:00
|
|
|
const descriptionSection = document.getElementById(torrentId + "_description");
|
|
|
|
const filelistSection = document.getElementById(torrentId + "_filelist");
|
|
|
|
const mediaInfoSection = document.getElementById(torrentId + "_mediainfo");
|
|
|
|
|
|
|
|
if(descriptionSection !== null){
|
|
|
|
torrent.elements.description = descriptionSection.querySelector("blockquote");
|
|
|
|
torrent.description = torrent.elements.description.textContent;
|
|
|
|
}
|
|
|
|
if(filelistSection !== null){
|
|
|
|
torrent.elements.filelist = filelistSection.querySelector("table");
|
|
|
|
torrent.filelist = [];
|
|
|
|
torrent.elements.filelist.querySelectorAll("tr").forEach((tableRow) => {
|
|
|
|
if(tableRow.querySelector("td > strong") !== null){
|
|
|
|
//Skip header
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
torrent.filelist.push({
|
|
|
|
path: tableRow.querySelector("td").textContent,
|
|
|
|
size: tableRow.querySelector("td:last-of-type").textContent //TODO: convert back to bytes
|
|
|
|
})
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if(mediaInfoSection !== null){
|
|
|
|
torrent.elements.mediainfo = mediaInfoSection;
|
|
|
|
let m_list = [];
|
|
|
|
torrent.elements.mediainfo.querySelectorAll("pre").forEach((mediainfoItem) => {
|
|
|
|
let m = parseMediaInfo(mediainfoItem.textContent);
|
|
|
|
if(m !== null){
|
|
|
|
m_list.push(m);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
if(m_list.length > 0){
|
|
|
|
torrent.mediainfo = m_list;
|
2021-11-21 14:06:34 +00:00
|
|
|
torrent.mediainfoSource = "mediainfo";
|
|
|
|
}
|
|
|
|
}else if(descriptionSection !== null){
|
|
|
|
//Find mediainfo tags
|
|
|
|
torrent.elements.description.querySelectorAll("input.spoilerButton").forEach((e) => {
|
|
|
|
let t = e.parentElement.querySelector("div.spoiler").textContent.trim();
|
|
|
|
if(t.indexOf("General") === 0){
|
|
|
|
let m = parseMediaInfo(t);
|
|
|
|
if(m !== null){
|
|
|
|
if(!("mediainfo" in torrent)){
|
|
|
|
torrent.mediainfo = [];
|
|
|
|
torrent.mediainfoSource = "description spoiler";
|
|
|
|
}
|
|
|
|
torrent.mediainfo.push(m);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-11-21 14:51:42 +00:00
|
|
|
if(!("mediainfo" in torrent)){
|
|
|
|
//Fallback, find General tag
|
|
|
|
let t = torrent.elements.description.parentElement.textContent.trim();
|
|
|
|
let index = t.indexOf("General");
|
|
|
|
if(index !== -1){
|
|
|
|
let m = parseMediaInfo(t.substr(index));
|
|
|
|
if(m !== null){
|
|
|
|
if(!("mediainfo" in torrent)){
|
|
|
|
torrent.mediainfo = [];
|
|
|
|
torrent.mediainfoSource = "description";
|
|
|
|
}
|
|
|
|
torrent.mediainfo.push(m);
|
2021-11-21 14:06:34 +00:00
|
|
|
}
|
|
|
|
}
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
torrentListing.push(torrent);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
{
|
|
|
|
{
|
|
|
|
let parentTd = document.querySelector("table.torrent_table tr > td");
|
|
|
|
parentTd.insertAdjacentElement("beforebegin", document.createElement("td"));
|
|
|
|
// Source + container + remux | Codec / Resolution / HDR | Audio + Dual + commentary | Text | OtherTags | Icons
|
|
|
|
parentTd.setAttribute("colspan", torrentTableColspan.toString());
|
|
|
|
|
|
|
|
document.querySelectorAll("table.torrent_table tr.edition_info > td").forEach((e) => {
|
|
|
|
e.setAttribute("colspan", (torrentTableColspan + 1 + 4).toString());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
torrentListing.forEach((torrent) => {
|
|
|
|
let parent = torrent.elements.link.parentElement;
|
|
|
|
let td = document.createElement("td");
|
|
|
|
|
|
|
|
torrent.elements.data.querySelector("td").setAttribute("colspan", (torrentTableColspan + 1 + 4).toString());
|
|
|
|
|
|
|
|
parent.parentElement.insertAdjacentElement("beforebegin", td);
|
|
|
|
parent.style["white-space"] = "nowrap";
|
|
|
|
td.append(parent);
|
|
|
|
|
|
|
|
Array.from(parent.childNodes).forEach((e) => {
|
|
|
|
if(e.nodeType === Node.TEXT_NODE && ["[", "]"].includes(e.textContent.trim())){
|
|
|
|
e.remove();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
console.log(torrentListing);
|
|
|
|
|
|
|
|
torrentListing.forEach((torrent) => {
|
|
|
|
try {
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
let infoCount = 0;
|
|
|
|
let warningCount = 0;
|
|
|
|
let dangerCount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
let tags = {
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
let warnings = {
|
|
|
|
general: [],
|
|
|
|
audio: [],
|
|
|
|
video: [],
|
|
|
|
text: []
|
|
|
|
}
|
|
|
|
|
|
|
|
let fileName = null;
|
|
|
|
|
|
|
|
if("mediainfo" in torrent && torrent.mediainfo.length > 0 && "mediainfo.general.complete_name" in torrent.mediainfo[0].general){
|
|
|
|
[fileName] = torrent.mediainfo[0].general.complete_name.split("/").slice(-1);
|
|
|
|
}else{
|
|
|
|
fileName = torrent.filelist[0].path;
|
|
|
|
}
|
|
|
|
|
|
|
|
//handle file tags
|
|
|
|
fileName.split(".").forEach((p) => {
|
|
|
|
if(p.toUpperCase() === "NF"){
|
|
|
|
tags.sourceName = "Netflix";
|
|
|
|
}else if(p.toUpperCase() === "ATVP"){
|
|
|
|
tags.sourceName = "Apple TV+";
|
|
|
|
}else if(p.toUpperCase() === "AMZN"){
|
|
|
|
tags.sourceName = "Amazon Video";
|
|
|
|
}else if(p === "HDR"){
|
|
|
|
tags.videoHDR = "HDR";
|
|
|
|
}else if(p === "HDR10"){
|
|
|
|
tags.videoHDR = "HDR10";
|
|
|
|
}else if(p === "DV"){
|
|
|
|
tags.videoHDR = "HDR DV";
|
|
|
|
}else if(p.toUpperCase() === "REMUX"){
|
|
|
|
tags.remux = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
fileName.split(/[ _\[\]]/).forEach((p) => {
|
|
|
|
if(p.toUpperCase() === "NETFLIX"){
|
|
|
|
tags.sourceName = "Netflix";
|
|
|
|
}else if(p === "HDR"){
|
|
|
|
tags.videoHDR = "HDR";
|
|
|
|
}else if(p === "HDR10"){
|
|
|
|
tags.videoHDR = "HDR10";
|
|
|
|
}else if(p === "DV"){
|
|
|
|
tags.videoHDR = "HDR DV";
|
|
|
|
}else if(p.toUpperCase().indexOf("REMUX") !== -1){
|
|
|
|
tags.remux = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-11-25 18:13:36 +00:00
|
|
|
let japaneseEpisodeMatch = fileName.match(/第[0-9.]+話/u);
|
|
|
|
if(japaneseEpisodeMatch !== null){
|
|
|
|
warnings.general.push(["warning", "Episode numbering is in Japanese format: example " + japaneseEpisodeMatch[0]]);
|
|
|
|
}
|
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
if("mediainfo" in torrent && torrent.mediainfo.length > 0){
|
|
|
|
let mediainfo = torrent.mediainfo[0];
|
|
|
|
|
|
|
|
let japaneseAudio = null;
|
|
|
|
let otherAudio = null;
|
|
|
|
let defaultAudio = null;
|
|
|
|
|
|
|
|
let englishSubs = null;
|
|
|
|
let defaultSubs = null;
|
|
|
|
|
|
|
|
switch(mediainfo.general.format){
|
|
|
|
case "Matroska":
|
|
|
|
tags.container = "MKV";
|
|
|
|
break;
|
|
|
|
case "BDAV":
|
|
|
|
tags.container = "M2TS";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-11-21 14:06:34 +00:00
|
|
|
if(torrent.mediainfoSource !== "mediainfo"){
|
|
|
|
warnings.general.push(["danger", "Mediainfo sourced from " + torrent.mediainfoSource + ". Consider reporting the torrent and providing it."])
|
|
|
|
}
|
2021-11-21 03:17:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
let video = mediainfo.video[0];
|
|
|
|
if(video !== null){
|
|
|
|
videoCodecs.every((codec) => {
|
|
|
|
let match = true;
|
2021-11-22 09:10:25 +00:00
|
|
|
let n = codec.name;
|
|
|
|
let l = codec.legacy;
|
|
|
|
let m = null;
|
2021-11-21 03:17:10 +00:00
|
|
|
for(const [key, value] of Object.entries(codec.match)){
|
|
|
|
if(value === null){
|
|
|
|
if(key in video){
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!(key in video)){
|
|
|
|
match = false;
|
|
|
|
break;
|
2021-11-22 09:10:25 +00:00
|
|
|
}else if (value instanceof RegExp){
|
|
|
|
if((m = video[key].match(value)) === null){
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-11-22 09:25:36 +00:00
|
|
|
if("groups" in m && typeof m.groups === "object"){
|
2021-11-22 09:23:11 +00:00
|
|
|
for(const [k, v] of Object.entries(m.groups)){
|
|
|
|
if(typeof v !== "undefined"){
|
|
|
|
n = n.replace('$' + k, v);
|
|
|
|
l = l.replace('$' + k, v);
|
|
|
|
}else{
|
|
|
|
n = n.replace('$' + k, "");
|
|
|
|
l = l.replace('$' + k, "");
|
|
|
|
}
|
2021-11-22 09:10:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}else if (video[key] !== value){
|
2021-11-21 03:17:10 +00:00
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(match){
|
2021-11-22 09:10:25 +00:00
|
|
|
tags.videoCodec = Object.assign({}, codec);
|
|
|
|
tags.videoCodec.name = n.trim();
|
|
|
|
tags.videoCodec.legacy = l.trim();
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return !match;
|
|
|
|
});
|
|
|
|
|
2021-11-21 13:15:27 +00:00
|
|
|
if("frame_rate" in video){
|
|
|
|
tags.videoFrameRate = video.frame_rate.split(" ")[0];
|
|
|
|
}else
|
|
|
|
|
|
|
|
if("original_frame_rate" in video){
|
|
|
|
tags.videoFrameRate = video.original_frame_rate.split(" ")[0];
|
|
|
|
}
|
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
let width = parseInt(video.width.replace(/[^0-9]/g, ""));
|
|
|
|
let height = parseInt(video.height.replace(/[^0-9]/g, ""));
|
|
|
|
|
2021-11-21 13:15:27 +00:00
|
|
|
if(((width <= 1280 && width >= 1200) || (width <= 960 && width >= 900)) && height > 480 && height <= 720){
|
2021-11-21 03:17:10 +00:00
|
|
|
tags.resolution = "720" + ((!("scan_type" in video) || video.scan_type === "Progressive") ? "p" : "i");
|
2021-11-21 13:15:27 +00:00
|
|
|
}else if(((width <= 1920 && width >= 1820) || (width <= 1440 && width >= 1340)) && height > 720 && height <= 1080){
|
2021-11-21 03:17:10 +00:00
|
|
|
tags.resolution = "1080" + ((!("scan_type" in video) || video.scan_type === "Progressive") ? "p" : "i");
|
2021-11-21 13:15:27 +00:00
|
|
|
}else if((width <= 3840 && width >= 3640) && height > 1080 && height <= 2160){
|
2021-11-21 03:17:10 +00:00
|
|
|
tags.resolution = "4K";
|
|
|
|
}else{
|
|
|
|
tags.resolution = width + "x" + height;
|
|
|
|
}
|
|
|
|
|
2021-11-21 13:15:27 +00:00
|
|
|
tags.aspectRatio = video.display_aspect_ratio;
|
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
if("color_primaries" in video && video.color_primaries === "BT.2020"){
|
|
|
|
tags.videoHDR = "HDR";
|
|
|
|
}
|
|
|
|
|
|
|
|
if("hdr_format" in video){
|
|
|
|
if(video.hdr_format.match(/Dolby Vision/) !== null){
|
|
|
|
tags.videoHDR = "HDR DV";
|
|
|
|
}else if(video.hdr_format.match(/SMPTE ST 2086/) !== null && video.hdr_format.match(/HDR10/) !== null){
|
|
|
|
tags.videoHDR = "HDR10";
|
|
|
|
}else if(video.hdr_format.match(/SMPTE ST 2094-40/) !== null && video.hdr_format.match(/HDR10/) !== null){
|
|
|
|
tags.videoHDR = "HDR10+";
|
|
|
|
}else if(video.hdr_format.match(/SL-HDR1/) !== null){
|
|
|
|
tags.videoHDR = "SL-HDR1";
|
|
|
|
}else if(video.hdr_format.match(/SL-HDR2/) !== null){
|
|
|
|
tags.videoHDR = "SL-HDR2";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if("writing_library" in video){
|
|
|
|
if(video.writing_library.match(/x265/) !== null){
|
|
|
|
tags.videoEncoder = "x265";
|
|
|
|
}else if(video.writing_library.match(/x264/) !== null){
|
|
|
|
tags.videoEncoder = "x264";
|
2021-11-21 15:26:00 +00:00
|
|
|
let versionMatch = video.writing_library.match(/ r(?<version>[0-9]+) /)
|
|
|
|
if(versionMatch !== null){
|
|
|
|
tags.videoEncoderVersion = parseInt(versionMatch.groups.version);
|
|
|
|
}
|
2021-11-22 09:23:11 +00:00
|
|
|
}else if(video.writing_library.match(/libaom/) !== null){
|
|
|
|
tags.videoEncoder = "libaom";
|
2021-11-21 03:17:10 +00:00
|
|
|
}else if(video.writing_library.match(/_nvenc/) !== null){
|
|
|
|
tags.videoEncoder = "NVENC";
|
2021-11-21 03:43:15 +00:00
|
|
|
warnings.video.push(["danger", "Found NVENC hardware-encoded stream"]);
|
2021-11-21 03:17:10 +00:00
|
|
|
}else if(video.writing_library.match(/_qsv/) !== null){
|
|
|
|
tags.videoEncoder = "QuickSync";
|
2021-11-21 03:43:15 +00:00
|
|
|
warnings.video.push(["danger", "Found QuickSync hardware-encoded stream"]);
|
2021-11-21 03:17:10 +00:00
|
|
|
}else if(video.writing_library.match(/_vaapi/) !== null){
|
|
|
|
tags.videoEncoder = "VAAPI";
|
2021-11-21 03:43:15 +00:00
|
|
|
warnings.video.push(["danger", "Found VAAPI hardware-encoded stream"]);
|
2021-11-21 03:17:10 +00:00
|
|
|
}else if(video.writing_library.match(/[^0-9A-F]/) !== null){
|
|
|
|
[tags.videoEncoder] = video.writing_library.split(" ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-21 15:37:46 +00:00
|
|
|
//Detect probably H264 remuxes
|
|
|
|
try{
|
|
|
|
if(
|
|
|
|
!("remux" in tags) &&
|
|
|
|
!("encoding_settings" in video) && !("writing_library" in video) &&
|
|
|
|
video.codec_id === "V_MPEG4/ISO/AVC" && video.format_profile === "High@L4.1" &&
|
|
|
|
video.format_settings.match(/CABAC \/ [234] Ref Frames/) !== null && width === 1920 && height === 1080 &&
|
|
|
|
video.frame_rate_mode === "Constant" &&
|
|
|
|
(!("bits_pixel_frame" in video) || parseFloat(video.bits_pixel_frame) > 0.5)
|
|
|
|
){
|
|
|
|
tags.remux = "probably";
|
|
|
|
}
|
|
|
|
}catch (e){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
if("encoding_settings" in video){
|
|
|
|
let match = null;
|
|
|
|
if((match = video.encoding_settings.match(/crf=(?<crf>[0-9.]+)/)) !== null){
|
|
|
|
tags.videoCRF = parseFloat(match.groups.crf).toFixed(1);
|
|
|
|
}
|
|
|
|
if(video.encoding_settings.match(/rc=2pass/) !== null){
|
|
|
|
tags.videoCRF = "2pass";
|
|
|
|
}
|
2021-11-21 15:37:46 +00:00
|
|
|
if(!("remux" in tags) && video.codec_id === "V_MPEG4/ISO/AVC" && (match = video.format_profile.match(/(?<profile>(baseline|main)[ 0-9]*)@/i)) !== null){
|
2021-11-21 03:43:15 +00:00
|
|
|
warnings.video.push(["warning", "Found encode using profile=" + match.groups.profile + " on encoding settings"]);
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
if(video.encoding_settings.match(/cabac=0/) !== null){
|
2021-11-21 03:43:15 +00:00
|
|
|
warnings.video.push(["info", "Found encode with CABAC disabled"]);
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
if(video.encoding_settings.match(/mbtree=0/) !== null){
|
2021-11-21 03:43:15 +00:00
|
|
|
warnings.video.push(["info", "Found encode with mbtree disabled"]);
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
if(video.encoding_settings.match(/bframes=0/) !== null){
|
2021-11-21 03:43:15 +00:00
|
|
|
warnings.video.push(["info", "Found encode with bframes disabled"]);
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
if(video.encoding_settings.match(/me=dia/) !== null){
|
2021-11-21 03:43:15 +00:00
|
|
|
warnings.video.push(["info", "Found encode with me=dia"]);
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-21 14:41:03 +00:00
|
|
|
mediainfo.audio.forEach((audio, index) => {
|
|
|
|
const isDefault = audio.default === "Yes";
|
|
|
|
|
|
|
|
if(isDefault){
|
|
|
|
defaultAudio = audio;
|
|
|
|
}
|
|
|
|
if("language" in audio && audio.language !== "Japanese" && audio.language !== "Unknown" && isDefault && torrentType.match(/Live Action/) === null){
|
|
|
|
warnings.audio.push(["info", "Default audio #"+(index+1)+" is not in Japanese"]);
|
|
|
|
}
|
|
|
|
if("title" in audio && audio.title.match(/comment/i) !== null){
|
|
|
|
tags.audioCommentary = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(audio.language === "Japanese"){
|
|
|
|
if(japaneseAudio === null){ // Pick first
|
|
|
|
japaneseAudio = audio;
|
|
|
|
}else{
|
|
|
|
const oldChannels = parseInt(japaneseAudio.channels.replace(" channels", ""));
|
|
|
|
const channels = parseInt(audio.channels.replace(" channels", ""));
|
|
|
|
if(channels > oldChannels){
|
|
|
|
japaneseAudio = audio;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}else if(audio.language === "Unknown" || !("language" in audio)){
|
|
|
|
if(mediainfo.audio.length === 1){
|
|
|
|
japaneseAudio = audio;
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
if(otherAudio === null){ // Pick first
|
|
|
|
otherAudio = audio;
|
|
|
|
}else{
|
|
|
|
const oldChannels = parseInt(otherAudio.channels.replace(" channels", ""));
|
|
|
|
const channels = parseInt(audio.channels.replace(" channels", ""));
|
|
|
|
if(channels > oldChannels){
|
|
|
|
otherAudio = audio;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-25 14:33:49 +00:00
|
|
|
const ratio = ("stream_size" in audio) ? parseFloat(audio.stream_size.match(/\((?<percentage>[0-9.]+)%\)$/).groups.percentage) : null;
|
2021-11-25 14:31:08 +00:00
|
|
|
|
2021-11-21 14:41:03 +00:00
|
|
|
if(!("remux" in tags) && audio.format === "PCM"){
|
|
|
|
warnings.audio.push(["warning", "BLOAT: Audio track #"+(index+1)+" is uncompressed PCM."]);
|
|
|
|
}
|
|
|
|
|
2021-11-25 14:31:08 +00:00
|
|
|
if(!("remux" in tags) && (audio.format === "FLAC" || audio.format.match(/^DTS/) !== null) && (ratio === null || (ratio > 10))){
|
2021-11-21 14:41:03 +00:00
|
|
|
let bitDepth = parseInt(audio.bit_depth.replace(/[^0-9]/g, ""));
|
|
|
|
if(bitDepth > 16){
|
|
|
|
warnings.audio.push(["warning", "BLOAT: Audio track #"+(index+1)+" is "+audio.format+" with bit depth greater than 16-bit, found "+bitDepth+"-bit."]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if(japaneseAudio !== otherAudio && otherAudio !== null && japaneseAudio !== null){
|
|
|
|
tags.audioCount = mediainfo.audio.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
let audio = japaneseAudio !== null ? japaneseAudio : (defaultAudio !== null ? defaultAudio : otherAudio);
|
|
|
|
if(audio !== null){
|
|
|
|
tags.audioChannels = parseInt(audio.channels.replace(" channels", ""));
|
|
|
|
|
|
|
|
audioCodecs.every((codec) => {
|
|
|
|
let match = true;
|
2021-11-22 09:10:25 +00:00
|
|
|
let n = codec.name;
|
|
|
|
let l = codec.legacy;
|
|
|
|
let m = null;
|
2021-11-21 14:41:03 +00:00
|
|
|
for(const [key, value] of Object.entries(codec.match)){
|
|
|
|
if(value === null){
|
|
|
|
if(key in audio){
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(!(key in audio)){
|
|
|
|
match = false;
|
|
|
|
break;
|
2021-11-22 09:10:25 +00:00
|
|
|
}else if (value instanceof RegExp){
|
|
|
|
if((m = audio[key].match(value)) === null){
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-11-22 09:25:36 +00:00
|
|
|
if("groups" in m && typeof m.groups === "object"){
|
2021-11-22 09:23:11 +00:00
|
|
|
for(const [k, v] of Object.entries(m.groups)){
|
|
|
|
if(typeof v !== "undefined"){
|
|
|
|
n = n.replace('$' + k, v);
|
|
|
|
l = l.replace('$' + k, v);
|
|
|
|
}else{
|
|
|
|
n = n.replace('$' + k, "");
|
|
|
|
l = l.replace('$' + k, "");
|
|
|
|
}
|
2021-11-22 09:10:25 +00:00
|
|
|
}
|
|
|
|
}
|
2021-11-21 14:41:03 +00:00
|
|
|
}else if (!(value instanceof RegExp) && audio[key] !== value){
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(match){
|
2021-11-22 09:10:25 +00:00
|
|
|
tags.audioCodec = Object.assign({}, codec);
|
|
|
|
tags.audioCodec.name = n.trim();
|
|
|
|
tags.audioCodec.legacy = l.trim();
|
2021-11-21 14:41:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return !match;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if("text" in mediainfo){
|
|
|
|
mediainfo.text.forEach((text) => {
|
|
|
|
const isSignsEntry = ("title" in text) ? text.title.match(/sign/i) !== null : false;
|
|
|
|
const isDefault = text.default === "Yes";
|
|
|
|
if(isSignsEntry && isDefault){
|
|
|
|
warnings.text.push(["warning", "Default subtitle is a Signs track"]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(isDefault){
|
|
|
|
defaultSubs = text;
|
|
|
|
}
|
|
|
|
|
2021-11-21 18:18:59 +00:00
|
|
|
if(!isSignsEntry && (text.language === "English" || ("title" in text && text.title.match(/english/i) !== null))){
|
2021-11-21 14:41:03 +00:00
|
|
|
if(englishSubs === null){
|
|
|
|
englishSubs = text;
|
|
|
|
}else{
|
|
|
|
if(text.codec_id === "S_TEXT/ASS" && englishSubs.codec_id !== "S_TEXT/ASS"){
|
|
|
|
englishSubs = text;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}else if(mediainfo.text.length === 1 && (text.language === "Unknown" || !("language" in text))){
|
|
|
|
englishSubs = text;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
let text = englishSubs !== null ? englishSubs : (defaultSubs !== null ? defaultSubs : (("text" in mediainfo && mediainfo.text.length > 0) ? mediainfo.text[0] : null));
|
2021-11-21 15:26:00 +00:00
|
|
|
|
|
|
|
let isTrackExternal = false;
|
|
|
|
let externalTrackFormat = null;
|
|
|
|
torrent.filelist.every((file) => {
|
|
|
|
const ext = file.path.split(".").slice(-1)[0].toUpperCase();
|
|
|
|
if(ext === "ASS" || ext === "SRT" || ext === "SSA" || ext === "MKS" || ext === "VTT" || ext === "SUB"){
|
|
|
|
isTrackExternal = true;
|
|
|
|
externalTrackFormat = ext;
|
|
|
|
}
|
|
|
|
return !isTrackExternal;
|
|
|
|
});
|
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
if(text !== null){
|
2021-11-21 17:39:10 +00:00
|
|
|
tags.subtitleCodec = text.codec_id === "S_TEXT/UTF8" ? "SRT" : text.format;
|
2021-11-21 15:26:00 +00:00
|
|
|
tags.subtitleTitle = "title" in text ? text.title : "";
|
2021-11-21 14:58:55 +00:00
|
|
|
|
2021-11-21 15:26:00 +00:00
|
|
|
if(isTrackExternal === false && torrent.tags.subtitleType === "Softsubs" && englishSubs === null){
|
2021-11-21 14:58:55 +00:00
|
|
|
warnings.text.push(["warning", "Could not find English labeled subtitles, but labeled Softsubs"]);
|
|
|
|
}else{
|
|
|
|
tags.subtitleType = "Softsubs";
|
|
|
|
}
|
2021-11-21 15:26:00 +00:00
|
|
|
}
|
2021-11-25 18:07:42 +00:00
|
|
|
if((tags.subtitleType === "Softsubs" || torrent.tags.subtitleType === "Softsubs") && (text === null || englishSubs === null)){
|
2021-11-21 13:15:27 +00:00
|
|
|
if(isTrackExternal){
|
|
|
|
tags.subtitleType = "Softsubs";
|
|
|
|
tags.subtitleCodec = "External " + externalTrackFormat;
|
|
|
|
warnings.text.push(["info", "Subtitle track is external"]);
|
|
|
|
}else if("subtitleType" in torrent.tags && torrent.tags.subtitleType !== "Hardsubs"){
|
|
|
|
warnings.text.push(["warning", "Could not find subtitles either on file listing or disk, probably hardsubbed?"]);
|
|
|
|
}
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
|
|
|
|
2021-11-21 15:26:00 +00:00
|
|
|
if("menu" in mediainfo){
|
2021-11-25 18:07:42 +00:00
|
|
|
//Check for chapters and ordered chapters
|
|
|
|
|
|
|
|
let chapterCount = 0;
|
2021-11-21 15:26:00 +00:00
|
|
|
for(const [key, value] of Object.entries(mediainfo.menu)){
|
|
|
|
let entryCount = 0;
|
|
|
|
value.split(" / ").forEach((i) => {
|
|
|
|
i = i.trim();
|
|
|
|
if(i.indexOf(":") !== -1){
|
|
|
|
entryCount++;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
if(entryCount > 1 && !("chapters" in tags)){
|
|
|
|
tags.chapters = "ordered";
|
2021-11-21 15:26:00 +00:00
|
|
|
warnings.general.push(["danger", "Found Ordered Chapters"]);
|
|
|
|
}
|
2021-11-25 18:07:42 +00:00
|
|
|
++chapterCount;
|
2021-11-21 15:26:00 +00:00
|
|
|
}
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
if(!("chapters" in tags) && chapterCount > 1){
|
|
|
|
tags.chapters = chapterCount
|
|
|
|
}
|
|
|
|
}
|
2021-11-21 15:26:00 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
//torrent.elements.entry.prepend("» ");
|
2021-11-21 15:26:00 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
}else{
|
|
|
|
torrent.elements.item.style["font-style"] = "italic";
|
|
|
|
//torrent.elements.item.style["text-decoration"] = "line-through";
|
2021-11-21 15:26:00 +00:00
|
|
|
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
warnings.text.push(["danger", "No valid mediainfo section found. Report torrent with MediaInfo."]);
|
|
|
|
}
|
2021-11-21 15:26:00 +00:00
|
|
|
|
2021-11-21 03:17:10 +00:00
|
|
|
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
for(const [key, value] of Object.entries(torrent.tags)){
|
|
|
|
if(!(key in tags)){
|
|
|
|
tags[key] = value;
|
2021-11-21 13:15:27 +00:00
|
|
|
}
|
2021-11-25 18:07:42 +00:00
|
|
|
}
|
2021-11-21 13:15:27 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
if(!("aspectRatio" in torrent.tags) && "aspectRatio" in tags){
|
|
|
|
torrent.tags.aspectRatio = tags.aspectRatio;
|
|
|
|
}
|
2021-11-21 15:26:00 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
let oldTagLine = getComparisonLine(torrent.tags);
|
|
|
|
let newTagLine = getComparisonLine(tags);
|
2021-11-21 15:26:00 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
if(newTagLine !== oldTagLine){
|
|
|
|
warnings.general.push(["danger", "Tag mismatch:\nold: " + oldTagLine + " !=\nnew: " + newTagLine]);
|
|
|
|
}
|
2021-11-21 15:26:00 +00:00
|
|
|
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
let messages = document.createElement("div");
|
|
|
|
messages.append(document.createElement("br"));
|
|
|
|
let h2 = document.createElement("h2");
|
|
|
|
h2.textContent = "Warning Messages";
|
|
|
|
messages.append(h2);
|
2021-11-21 15:26:00 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
for(const [key, value] of Object.entries(warnings)){
|
|
|
|
if(value.length > 0){
|
2021-11-21 03:17:10 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
let h3 = document.createElement("h3");
|
|
|
|
h3.textContent = key.toUpperCase();
|
|
|
|
messages.append(h3);
|
2021-11-21 03:17:10 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
let messageList = document.createElement("ul");
|
2021-11-21 03:17:10 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
for(let v of value){
|
|
|
|
let li = document.createElement("li");
|
|
|
|
li.style.float = "inherit";
|
|
|
|
let value = "";
|
|
|
|
if(Array.isArray(v)){
|
2021-11-21 03:17:10 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
switch (v[0]){
|
|
|
|
case "info":
|
|
|
|
infoCount++;
|
|
|
|
value = "info: " + v[1];
|
|
|
|
break;
|
|
|
|
case "warning":
|
|
|
|
warningCount++;
|
|
|
|
value = "warning: " + v[1];
|
|
|
|
break;
|
|
|
|
case "danger":
|
|
|
|
dangerCount++;
|
|
|
|
value = "danger: " + v[1];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
++warningCount;
|
|
|
|
value = v;
|
|
|
|
}
|
2021-11-21 03:17:10 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
if(value.includes("\n")){
|
|
|
|
let pre = document.createElement("pre");
|
|
|
|
pre.textContent = value;
|
|
|
|
li.append(pre);
|
|
|
|
}else{
|
|
|
|
li.textContent = value;
|
|
|
|
}
|
2021-11-21 03:43:15 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
messageList.append(li);
|
|
|
|
}
|
2021-11-21 13:15:27 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
messages.append(messageList);
|
|
|
|
messages.append(document.createElement("br"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
messages.append(document.createElement("hr"));
|
2021-11-21 13:15:27 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
if(infoCount > 0 || warningCount > 0 || dangerCount > 0){
|
|
|
|
if("description" in torrent.elements){
|
|
|
|
torrent.elements.description.prepend(messages);
|
|
|
|
}
|
|
|
|
}
|
2021-11-21 13:15:27 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
/*while(torrent.elements.entry.firstChild){
|
|
|
|
torrent.elements.entry.firstChild.remove();
|
|
|
|
}*/
|
|
|
|
torrent.elements.entry.parentElement.remove();
|
2021-11-21 13:15:27 +00:00
|
|
|
|
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
let entries = getEntryLine(tags, infoCount, warningCount, dangerCount);
|
2021-11-21 13:15:27 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
let lastTd = torrent.elements.item.querySelector("td");
|
2021-11-21 13:15:27 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
let onclickFn = (e) => {
|
|
|
|
torrent.elements.data.classList.toggle("hide");
|
|
|
|
e.preventDefault();
|
|
|
|
};
|
2021-11-21 13:15:27 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
["icons", "source", "video", "audio", "text", "other"].forEach((k) => {
|
|
|
|
let td = document.createElement("td");
|
|
|
|
td.style["white-space"] = "nowrap";
|
|
|
|
if(k !== "other"){
|
|
|
|
td.style["width"] = "1%";
|
|
|
|
}
|
|
|
|
td.style["cursor"] = "pointer";
|
2021-11-21 13:15:27 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
let a = document.createElement("a");
|
|
|
|
if(tags.snatched){
|
|
|
|
a.classList.add("snatched-torrent");
|
2021-11-21 03:17:10 +00:00
|
|
|
}
|
2021-11-25 18:07:42 +00:00
|
|
|
a.setAttribute("href", torrent.elements.entry.href);
|
2021-11-21 03:17:10 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
a.addEventListener("click", (e) => e.preventDefault());
|
|
|
|
td.addEventListener("click", onclickFn);
|
2021-11-21 03:17:10 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
entries[k].forEach((e) => {
|
|
|
|
if(a.firstChild){
|
|
|
|
a.append(" / ");
|
2021-11-21 03:43:15 +00:00
|
|
|
}
|
2021-11-25 18:07:42 +00:00
|
|
|
a.append(e);
|
|
|
|
});
|
2021-11-21 14:51:42 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
td.append(a);
|
2021-11-21 03:17:10 +00:00
|
|
|
|
2021-11-25 18:07:42 +00:00
|
|
|
lastTd.insertAdjacentElement("afterend", td)
|
|
|
|
lastTd = td;
|
|
|
|
});
|
2021-11-21 03:17:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
}catch (e){
|
|
|
|
console.log("Error:", e);
|
|
|
|
console.log(torrent);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
//21:28:16 <+AMM> subs, signage, chapters, titles, codecs, containers
|
|
|
|
// 21:28:20 <+AMM> What is good, what is bad
|