Skip to content

Instantly share code, notes, and snippets.

@Neinei0k
Last active August 8, 2020 07:32
Show Gist options
  • Save Neinei0k/f26fc3c0f0aad6a78c308c9589f0c72a to your computer and use it in GitHub Desktop.
Save Neinei0k/f26fc3c0f0aad6a78c308c9589f0c72a to your computer and use it in GitHub Desktop.
Import list of titles, people or characters in the imdb list. More info: https://greasyfork.org/en/scripts/23584-imdb-list-importer
// ==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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment