Greasy Fork

Greasy Fork is available in English.

IMDB List Importer

Import list of titles, people or characters in the imdb list

当前为 2017-07-16 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         IMDB List Importer
// @namespace    Neinei0k_imdb
// @include      http://www.imdb.com/list/edit*
// @version	     5.1
// @grant        none
// @description  Import list of titles, people or characters in the imdb list
// ==/UserScript==

var o = {

init: function(e) {
	this.etext = e.querySelector('textarea');
	this.efile = e.querySelector('input[type="file"]');
	this.eready = e.children[10];
	var checkboxes = e.querySelectorAll('input[type="checkbox"]');
	this.source = checkboxes[0]; 
	this.csv = checkboxes[1];
	this.unique = checkboxes[2];
},

run: function(event) {
	this.text = this.etext.value;
	if (this.source.checked) { // read data from file
		var file = this.efile.files[0];
		if (file !== undefined) {
			this.log("i","Reading file " + file.name);
			var r = new FileReader();
			r.onload = this.file_onload.bind(this);
			r.readAsText(file);
		} else {
			this.log("e","File is undefined");
		}
	} else { // read data from input element
		this.add_list(this.create_list());
	}
},

file_onload: function(e) {
	if (e.target.error === null) {
		this.text = e.target.result;
		this.add_list(this.create_list());
	} else {
		this.log("e","File reading error: " + e.target.error);
	}
},

log: function(level,msg) {
	var l = "";
	if (level === "i") l = "Info: ";
	else if (level === "e") l = "Error: ";
	if (l.length !== 0)
		console.log("IMDB List Importer: " + l + msg);
	if (level == "n" || level == "e")
		this.eready.innerText = msg;
},

create_list: function() {
	var re;
	// Find type of the list
	if (document.getElementsByClassName('list_characters').length !== 0) {
		this.log("i", "List type: characters");
		re = "ch";
	} else if (document.getElementsByClassName('list_people').length !== 0) {
		this.log("i", "List type: people");
		re = "nm";
	} else if (document.getElementsByClassName('list_titles').length !== 0) {
		this.log("i", "List type: titles");
		re = "tt";
	} else {
		this.log("e","Could not determine type of the list");
		return [];
	}
	re += "[0-9]{7}";

	if (this.csv.checked) {
		return this.read_csv(re);
	} else {
		re = new RegExp(re);
		var list = [];
		var e;
		var text = this.text;
		while ((e = re.exec(text)) !== null) {
			var flag = '';
			if (this.unique.checked) flag = 'g';
			text = text.replace(new RegExp(e[0], flag), '');
			list.push({const: e[0], description: ""});
		}
		return list;
	}
},

read_csv: function(re) {
	re = new RegExp("^" + re + "$");
	var list = [];
	text = this.text.split('\n');

	// Find const and description field numbers.
	try {
		var fl = JSON.parse('[' + text[0] + ']');
		var fll = fl.length
		var const_field = fl.indexOf('const');
		if (const_field === -1) throw "Field 'const' not found.";
		var desc_field = fl.indexOf('description');
		if (desc_field === -1) throw "Field 'description' not found.";
	} catch (err) {
		this.log("e","Input line 1: " + err);
		return [];
	}
	this.log("i","Found csv file fields const(" + const_field +
	             ") and description(" + desc_field + ")");
	text.shift();

	// Add elements to the list
	for (var i = 0; i < text.length; i++) {
		if (text[i].trim().length === 0)
			continue;
		try {
			fl = JSON.parse('[' + text[i] + ']');
			if (fll !== fl.length) throw "Invalid number of fields.";
			if (re.exec(fl[const_field]) === null) throw "Invalid 'const' field.";
		} catch (err) {
			this.log("e","Input line " + (i+2) + ": " + err);
			return [];
		}
		if (this.unique.checked) {
			var exists = list.findIndex(function(v){
				return v.const === fl[const_field];
			});
			if (exists !== -1) continue;
		}
		list.push({const: fl[const_field],description: fl[desc_field]});
	}
	return list;
},
	
add_list: function(list) {
	if (list.length === 0)
		return;

	var msg = "Elements to add: ";
	for (var i in list)
		msg += list[i].const + ",";
	this.log("i",msg);

	var l = {};
	l.list = list;
	l.ready = 0;
	l.list_id = /ls[0-9]{1,}/.exec(location.href)[0];
	this.sendNext(l);
},

sendNext: function(l) {
	this.log("i",'Add element ' + l.ready + ': ' + l.list[l.ready].const);
	this.send_request(this.check_item, l, 'const=' + l.list[l.ready].const +
	                                     '&list_id=' + l.list_id);
},

send_request: function(f,l,d) {
	var x = new XMLHttpRequest();
	x.onreadystatechange = f.bind(this,l);
	x.open('POST', '/list/_ajax/edit', true);
	x.setRequestHeader('Content-Type',
	  'application/x-www-form-urlencoded; charset=UTF-8');
	x.send(d);
},

check_item: function(l, e) {
	this.log("i","Add element(" + l.list[l.ready].const +
	             ") request: readyState(" + e.target.readyState +
	             "), status(" + e.target.status + ")");
	if (e.target.readyState == 4 && e.target.status == 200) {
		if (l.list[l.ready].description.length !== 0) {
			this.send_request(this.check_item_desc, l,
			                  'description=' + l.list[l.ready].description +
			                  '&list_id=' + l.list_id + '&list_item_id=' +
			                  JSON.parse(e.target.responseText).list_item_id);
		} else {
			this.showReady(l);
		}
	}
},

check_item_desc: function(l,e) {
	this.log("i","Add element(" + l.list[l.ready].const +
	             ") description request: readyState(" + e.target.readyState +
	             "), status(" + e.target.status + ")");
	if (e.target.readyState == 4 && e.target.status == 200) {
		this.showReady(l);
	}
},

showReady: function(l) {
	l.ready += 1;
	this.log("n",'Ready ' + l.ready + ' of ' + l.list.length + '.');
	if (l.ready == l.list.length) {
		location.reload();
	} else {
		this.sendNext(l);
	}
},

change: function(e) {
	var s = e.target.checked;
	this.etext.disabled = s;
	this.efile.disabled = !s;
},

};

var c = window.File && window.FileReader && window.FileList && window.Blob;
var div = document.createElement('div');
div.setAttribute('class', 'add');
var s = '<textarea style="background-color: white"></textarea><br>';
if (c) {
	s += '<input type="file" disabled><br>';
	s += '<label>';
	s += '<input type="checkbox" style="width: initial;">';
	s += '<span style="font-weight: normal;">';
	s += 'Import from file (otherwise import from text)';
	s += '</span>';
	s += '</label><br>';
} else {
	s += '<span style="font-weight: normal;">';
	s += 'Looks like your browser does not support File API for reading local files.';
	s += '</span><br>';
}
s += '<label>';
s += '<input type="checkbox" checked style="width: initial;">';
s += '<span style="font-weight: normal;">Data from .csv file</span>';
s += '</label><br>';
s += '<label>';
s += '<input type="checkbox" style="width: initial;">';
s += '<span style="font-weight: normal;">Add only unique elements</span>';
s += '</label><br>';
s += '<div>Set-up parameters. Insert text or choose file. Press \'Import List\' button.</div>';
s += '<button class="btn">Import List</button>';
div.innerHTML = s;

o.init(div);
div.querySelector('button').addEventListener('click',o.run.bind(o),false);
if (c) {
	o.source.addEventListener('change',o.change.bind(o),false);
}

var list_edit = document.querySelector('.list_edit');
var footer = document.querySelector('.footer');
list_edit.insertBefore(div, footer);