Last active
August 8, 2020 07:32
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==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