Greasy Fork

Filmografie von IMDb nach Wikipedia

Wandle die Filmografie von IMDb mithilfe von Wikidata in Wikipedia-Quelltext um.

当前为 2020-04-03 提交的版本,查看 最新版本

// ==UserScript==
// @name         Filmografie von IMDb nach Wikipedia
// @namespace    https://greasyfork.org/users/21515
// @description  Wandle die Filmografie von IMDb mithilfe von Wikidata in Wikipedia-Quelltext um.
// @author       CennoxX
// @contact      [email protected]
// @version      1.2.0
// @connect      www.wikidata.org
// @connect      www.imdb.com
// @match        https://www.imdb.com/name/*
// @grant        GM.xmlHttpRequest
// @grant        GM.setClipboard
// @grant        GM.registerMenuCommand
// @grant        unsafeWindow
// @license      MIT
// ==/UserScript==
/* jshint esversion: 6 */
(function() {
    'use strict';

    unsafeWindow.ladeFilmografie = function(episodeLabel,showShort,calledByMenu=false) {
        var work = document.querySelector('#filmo-head-actor,#filmo-head-actress').nextElementSibling.children;
        var filmography = [];
        var request = 0;
        var done = 0;

        document.links.forEach(link => {
            if (link.innerText.startsWith('Show all')){
                link.click();
            }
        });

        setTimeout(function(){
            work.forEach( w => {
                var credit = new Credit();
                var years = w.querySelector('.year_column').innerText.trim().split('/')[0].split('-');
                credit.yearFrom = years[0];
                credit.yearTo = years[1]?years[1]:0;
                credit.dt = w.querySelector('a').innerText.replace(' - ', ' – ').replace('...', '…');
                var entry = w.innerHTML.split('</b>')[1];
                credit.type = entry.split('<br>')[0].replace(/\)?\n\(voice/,'').trim()///([A-Z][a-z]+ version, )?voice
                    .replace(/\(Documentary short\)/, 'Dokumentar-Kurzfilm')
                    .replace(/\((TV Movie d|D)ocumentary\)/, 'Dokumentarfilm')
                    .replace(/\(TV Series short\)/, 'Webserie')
                    .replace(/\(TV Series( documentary)?\)/, 'Fernsehserie')
                    .replace(/\(TV Mini-Series( documentary)?\)/, 'Miniserie')
                    .replace(/\(TV Movie\)/, 'Fernsehfilm')
                    .replace(/\((Video s|TV S|TV Mini-Series s|S)hort\)/, 'Kurzfilm')
                    .replace(/\((Video|uncredited)\)/, '').split('\n')[0];
                if (!credit.type.includes('in_production') && !credit.type.includes('Video Game') && (showShort || !credit.type.includes('Kurzfilm'))) {
                    credit.imdbid = w.getAttribute('id').split('-')[1];
                    getItemFromWikidata(credit.imdbid);
                    if (credit.type.includes('serie')) {
                        var voiceEpisodes = 0;
                        var allEpisodes = w.querySelectorAll('.filmo-episodes');
                        allEpisodes.forEach(episode => {
                            if (!episode.innerText.includes('credit only') && episode.innerText != 'Show less') {
                                credit.numberOfEpisodes++;
                                credit.episodeName = episode.querySelector('a').href.split('/')[4];
                                if (episode.innerText.includes('voice')) {
                                    voiceEpisodes++;
                                }
                            }
                        });
                        if (credit.numberOfEpisodes == 1) {
                            getEpisodeNumberFromIMDb(credit.episodeName);
                        } else {
                            credit.episodeName = '';
                        }
                        credit.voice = (credit.numberOfEpisodes && voiceEpisodes == credit.numberOfEpisodes);
                    } else {
                        credit.voice = (entry.split('<br>').length>1 && entry.split('<br>')[1].includes('voice')) || (entry.split('\n').length>1 && entry.split('\n')[1].includes('voice'));
                    }
                    filmography.push(credit);
                }
            });

            filmography = filmography.reverse().sort(function(a,b) {
                return a.yearFrom - b.yearFrom;
            });

            var checkIfCompleted = setInterval(function() {
                console.clear();
                if (request === 0 || (done/request) != 1) {
					console.log('requests:',done,'/',request);
                } else {
                    var formattedFilmography = '== Filmografie ==\n';
                    filmography.forEach(function(entry) {
                        formattedFilmography += entry.toString();
                    });
                    GM.setClipboard (formattedFilmography);
                    var successMessage = 'Filmografie wurde erfolgreich kopiert.';
                    if (calledByMenu){
                        alert(successMessage);
                    } else {
                        console.log(formattedFilmography);
                        console.log(successMessage);
                    }
                    clearInterval(checkIfCompleted);
                }
            }, 1000);

            function getItemFromWikidata(imdbid) {
                request++;
                GM.xmlHttpRequest({
                    method: 'GET',
                    url: 'https://www.wikidata.org/w/api.php?action=query&format=json&list=search&srsearch=haswbstatement:P345=' + imdbid,
                    onload: function(response) {
                        done++;
                        if (response.responseText.length > 0) {
                            var jsonObj = JSON.parse(response.responseText);
                            var credit = filmography.find(c => {
                                return c.imdbid == imdbid || c.episodeid == imdbid;
                            });
                            if (jsonObj.query.searchinfo.totalhits > 0) {
                                var wikidataid = jsonObj.query.search[0].title;
                                if (credit.imdbid == imdbid){
                                    credit.link = wikidataid;
                                } else {
                                    credit.episodeid = wikidataid;
                                }
                                getDataFromWikidata(wikidataid);
                            } else if (credit.imdbid == imdbid){
                                getDataFromIMDb(imdbid);
                            }
                        }
                    },
                    onerror: function(response) {
                        done++;
                        console.log('Error in fetching contents: ' + response.responseText);
                    }
                });
            }

            function getDataFromWikidata(wikidataid) {
                request++;
                GM.xmlHttpRequest({
                    method: 'GET',
                    url: 'https://www.wikidata.org/w/api.php?action=wbgetentities&format=json&props=sitelinks|claims|labels&sitefilter=dewiki&ids=' + wikidataid,
                    onload: function(response) {
                        done++;
                        if (response.responseText.length > 0) {
                            var jsonObj = JSON.parse(response.responseText);
                            var credit = filmography.find(c => {
                                return c.link == wikidataid || c.episodeid == wikidataid;
                            });
                            if (credit.link == wikidataid) { //get dt, ot, link
                                if (typeof Object.values(jsonObj.entities)[0].sitelinks.dewiki != 'undefined') { //wikipedia article
                                    credit.link = Object.values(jsonObj.entities)[0].sitelinks.dewiki.title;
                                } else if (typeof Object.values(jsonObj.entities)[0].labels.de != 'undefined') {//wikidata label
                                    credit.link = '';
                                    credit.dt = Object.values(jsonObj.entities)[0].labels.de.value;
                                } else {
                                    credit.link = '';
                                }
                                if (typeof Object.values(jsonObj.entities)[0].claims.P1476 != 'undefined') { //check if OT of entity exists
                                    credit.ot = Object.values(jsonObj.entities)[0].claims.P1476[0].mainsnak.datavalue.value.text.replace(/'/g,'’');
                                } else {
                                    getDataFromIMDb(credit.imdbid);
                                }
                            } else { //get episode name
                                if (typeof Object.values(jsonObj.entities)[0].sitelinks.dewiki != 'undefined') { //wikipedia article
                                    var article = Object.values(jsonObj.entities)[0].sitelinks.dewiki.title;
                                    if (article.slice(-1) == ')'){
                                        article += `|${article.split(' (')[0]}`;
                                    }
                                    credit.episodeName = ` ''[[${article}]]''`;
                                } else if (typeof Object.values(jsonObj.entities)[0].labels.de != 'undefined') {//wikidata label
                                    credit.episodeName += ` ''${Object.values(jsonObj.entities)[0].labels.de.value}''`;
                                }
                            }
                        }
                    },
                    onerror: function(response) {
                        done++;
                        console.log('Error in fetching contents: ' + response.responseText);
                    }
                });
            }

            function getDataFromIMDb(imdbid) {
                request++;
                GM.xmlHttpRequest({
                    method: 'GET',
                    url: 'https://www.imdb.com/title/' + imdbid,
                    onload: function(response) {
                        done++;
                        if (response.responseText.length > 0) {
                            var htmlText = response.responseText;
                            var ot;
                            if (htmlText.indexOf('originalTitle') != -1) {
                                ot = (/<div class="originalTitle">(.*?)<span/m).exec(htmlText)[1];
                            } else {
                                ot = (/<title>(.*?) \(/m).exec(htmlText)[1];
                            }
                            filmography.find(c => {
                                return c.imdbid == imdbid;
                            }).ot = ot.replace('&amp;', '&').replace('...', '…').replace(' - ', ' – ');
                        }
                    },
                    onerror: function(response) {
                        done++;
                        console.log('Error in fetching contents: ' + response.responseText);
                    }

                });
            }

            function getEpisodeNumberFromIMDb(imdbid) {
                request++;
                GM.xmlHttpRequest({
                    method: 'GET',
                    url: 'https://www.imdb.com/title/' + imdbid,
                    onload: function(response) {
                        done++;
                        if (response.responseText.length > 0) {
                            var htmlText = response.responseText;
                            var credit = filmography.find(c => {
                                return c.episodeName == imdbid;
                            });
                            var episodeNumber = (/<div class="bp_heading">Season (.*?) <span class="ghost">\|<\/span> Episode (.*?)<\/div>/m).exec(htmlText);
                            if (episodeNumber !== null && episodeNumber.length == 3){
                                credit.episodeName = episodeNumber[1]+'x'+(episodeNumber[2].length == 1?'0':'')+episodeNumber[2];
                                credit.episodeid = imdbid;
                                getItemFromWikidata(imdbid);
                            } else {
                                credit.episodeName = '';
                            }
                        }
                    },
                    onerror: function(response) {
                        done++;
                        console.log('Error in fetching contents: ' + response.responseText);
                    }

                });
            }

            function Credit () {
                this.numberOfEpisodes = 0;
                this.episodeid = '';
                this.formatTitle = function(title = ''){
                    return title.replace(/[-–:., \d’'!]/g, '').toLowerCase();
                };
                this.compareTitles = function(titleA,titleB){
                    return this.formatTitle(titleA) == this.formatTitle(titleB);
                };
                this.getYearPart = function(){
                    var currentYear = new Date().getFullYear();
                    if (this.type.includes('serie') && this.numberOfEpisodes > 1 && (this.yearFrom == currentYear || (this.yearTo && this.yearTo == currentYear))){
                        return `seit ${this.yearFrom}`;
                    }
                    if (!this.yearTo ){
                        return this.yearFrom;
                    }
                    return `${this.yearFrom}–${this.yearTo}`;
                };
                this.getTitlePart = function(){
                    if (!this.link){
                        return this.dt;
                    }
                    if (this.link.slice(-1) == ')'){
                        this.dt = this.link.split(' (')[0];
                        return `[[${this.link}|${this.dt}]]`;
                    }
                    this.dt = this.link;
                    return `[[${this.link}]]`;
                };
                this.getDescriptionPart = function(){
                    if (!this.compareTitles(this.ot, this.dt) && !this.type && !this.voice){
                        return ` ''(${this.ot})''`;
                    }
                    var descriptionPart = '';
                    if (!this.compareTitles(this.ot, this.dt)){
                        descriptionPart += ` (''${this.ot}''`;
                    }
                    if (this.type){
                        descriptionPart += (descriptionPart?', ':' (') + this.type;
                    }
                    if (!`${this.getYearPart()}`.startsWith('seit')){
                        if (this.numberOfEpisodes>1){
                            descriptionPart += `, ${this.numberOfEpisodes} ${episodeLabel}n`;
                        } else if (this.numberOfEpisodes && this.episodeName){
                            descriptionPart += `, ${episodeLabel} ${this.episodeName}`;
                        }else if (this.numberOfEpisodes){
                            descriptionPart += `, eine ${episodeLabel}`;
                        }
                    }
                    if (this.voice){
                        descriptionPart += (descriptionPart?', ':' (') + 'Sprechrolle';
                    }
                    descriptionPart += descriptionPart?')':'';
                    return descriptionPart;
                };
                this.toString = function(){
                    return `* ${this.getYearPart()}: ${this.getTitlePart()}${this.getDescriptionPart()}\n`;
                };
            }
        }, 3000);

        return 'Filmografie lädt …';
    };

    GM.registerMenuCommand('Filmografie laden',()=>{
        unsafeWindow.ladeFilmografie('Folge', true, true);
    },'f');

    console.log('Um die Filmografie mit Standardeinstellungen zu laden, genügt ein Klick im Menü des Userscripts auf "Filmografie laden".\n'+
                'Um die Filmografie mit erweiterten Einstellungen zu laden, kann in der Console "ladeFilmografie(episodeLabel,showShort);" aufgerufen werden.\n'+
                'Dabei steht "episodeLabel" für die verwendete Bezeichnung "Folge" oder "Episode" und "showShort" dafür, ob Kurzfilme aufgeführt werden sollen oder nicht (true oder false).');
})();