// ==UserScript== // @name Get label from Fernsehserien.de // @namespace https://greasyfork.org/users/21515 // @version 0.2.2 // @description Offer Fernsehserien.de label based on episode number or title as Wikidata label // @author CennoxX // @contact cesar.bernard@gmx.de // @homepage https://twitter.com/CennoxX // @match https://www.wikidata.org/wiki/* // @icon https://www.google.com/s2/favicons?sz=64&domain=wikidata.org // @grant GM.xmlHttpRequest // @downloadURL none // ==/UserScript== /* jshint esversion: 6 */ /* eslint quotes: ["warn", "double", "avoid-escape"]*/ /* eslint curly: "off"*/ /* globals jQuery, $, mw */ (function(){ "use strict"; var correct = false; var added = false; var itemId = mw.config.get("wbEntityId"); if (!itemId){ return; } function compareString(title){ return title.trim().toLowerCase().replace(/\(?(?:part)? ?(\d+?)\)?$/i, "$1").replace(/&/i, "and").replace(/^the |^a |[\u200B-\u200D\uFEFF]| |\.|'|’|\(|\)|:|,|‚|\?|!|„|“|"|‘|…|\.|—|–|-/gi,""); } async function checkTitle(ep, oldTitle, tryByNumber){ var titles = [...ep.querySelectorAll("div:nth-child(7)>span")].map(i => i.innerText); var german = titles[0].replace(/ \((\d+)\)$/," – Teil $1").replace(/, Teil (\d+)$/," – Teil $1").replace(/ \(Teil (\d+)\)$/," – Teil $1"); var english = titles[1]; var deLabel = null; var insertElem = ' ' + ' '; var deLabelsDiv = $("div.wikibase-entitytermsview-labels"); deLabelsDiv.append(insertElem); deLabelsDiv.find(".wb-item-delabel").click(submitDeLabel); return await new Promise(resolve => { var stopInterval = setInterval(()=>{ if (deLabel != null){ if ([...document.querySelectorAll(".wb-item-delabel")].filter(i => i.innerText==german).length==0){ var descr = deLabel.nextElementSibling; descr.innerText = `(${english})`; var titleA = compareString(oldTitle); var titleB = compareString(english); correct = titleA == titleB && german != "–"; if (!correct && !tryByNumber && german != "–" && (titleA==titleB.replace(/\d/g,"") || titleB==titleA.replace(/\d/g,""))){ german = german.split(" – Teil ")[0]; correct = true; } deLabel.innerText = german; var color = ""; if (tryByNumber && correct) color = "lightgreen"; else if (!tryByNumber && correct) color = "lightyellow"; else color = "lightpink"; descr.style.backgroundColor = color; } clearInterval(stopInterval); resolve(correct); } var deLabels = document.querySelectorAll(".wb-item-delabel"); deLabel = deLabels[deLabels.length-1]; },500); }); } function getByTitle(ep, oldTitle, html, tryByTitle){ var originalTitle = [...html.querySelectorAll(".episodenliste-schmal")].filter(i => { var titleA = compareString(i.innerText); var titleB = compareString(oldTitle); if (tryByTitle) return titleA == titleB; else return titleA.replace(/\d/g,"") == titleB.replace(/\d/g,""); }); if (originalTitle.length>0) ep = originalTitle[0].closest("a"); return ep; } function getByLevenshteinDistance(ep, oldTitle, html){ var distMap = [...html.querySelectorAll(".episodenliste-schmal")].map(i => { var titleA = compareString(i.innerText); var titleB = compareString(oldTitle); var dist = levenshteinDistance(titleA,titleB); return({ep:i,dist}); }); var minDist = distMap.reduce(function(prev, curr) { return prev.dist < curr.dist ? prev : curr; }); console.log("levenshtein distance:",minDist.dist); return minDist.ep.closest("a"); } function levenshteinDistance(str1, str2){ var track = Array(str2.length + 1).fill(null).map(() => Array(str1.length + 1).fill(null)); for (let i = 0; i <= str1.length; i += 1) { track[0][i] = i; } for (let j = 0; j <= str2.length; j += 1) { track[j][0] = j; } for (let j = 1; j <= str2.length; j += 1) { for (let i = 1; i <= str1.length; i += 1) { var indicator = str1[i - 1] === str2[j - 1] ? 0 : 1; track[j][i] = Math.min( track[j][i - 1] + 1, track[j - 1][i] + 1, track[j - 1][i - 1] + indicator, ); } } return track[str2.length][str1.length]; } var mainLoop = setInterval(async()=>{ if (typeof $ != "undefined") { if (document.querySelector(".wikibase-labelview-text").innerText=="Keine Bezeichnung vorhanden"){ var oldTitle = document.querySelector(".wikibase-title-label span")?.innerText; //todo: get labels from languages that are not fallback if (oldTitle != null){ clearInterval(mainLoop); var season = document.querySelector('[data-property-id="P4908"] .wikibase-snakview-value')?.innerText.split("/Staffel ").pop(); var episode = document.querySelector('[data-property-id="P4908"] [href="/wiki/Property:P1545"]')?.closest(".wikibase-snakview").querySelector(".wikibase-snakview-value").innerText; var episodeNumber = ""; if (episode != null) episodeNumber = season+"x"+(episode[1]?"":"0")+episode; var series = document.querySelector('[data-property-id="P179"] .wikibase-snakview-value a').href.split("/")[4]; var response = await fetch(`https://query.wikidata.org/sparql?query=SELECT%20*%20WHERE%20%7B%0A%20%20wd%3A${series}%20wdt%3AP5327%20%3Fid.%0A%7D&format=json`); var data = await response.json(); var fsid = data.results.bindings[0].id.value; var epGuide = `https://www.fernsehserien.de/${fsid}/episodenguide`; //console.clear(); var result = await GM.xmlHttpRequest({ method: "GET", url: epGuide, onload: function(response) { return response; } }); var html=document.createElement("div"); html.innerHTML = result.responseText; fsid = html.querySelector('meta[property="og:url"]').content.split("/")[3]; var ep = null; var deLabelsParent = $("#wb-item-" + itemId + " div.wikibase-entitytermsview-heading"); var deLabelsDOM = $('