У моих друзей есть сайт для слепых. Они создают сайт, чтобы помочь сообществу слабовидящих загрузить несколько аудиофильмов для прослушивания на go. Я хочу помочь им составить список IMDB mov ie для перечисления всех этих названий.
Я использовал Microsoft Excel и какую-то программу для веб-сканирования, чтобы собрать данные, затем создать файл CSV и импортировать его в на сайте IMDB в списке mov ie моего аккаунта. Случилось так, что есть несколько пользовательских сценариев, написанных для Google Chrome для работы импорта. Я могу сделать текстовый файл CSV, содержащий идентификаторы mov ie IMDB и описание фильмов в парах, разделенных запятыми, а затем использовать сценарии для загрузки файла и затем выполнить импорт.
Но возникла проблема. Когда я пытаюсь запустить скрипт для выполнения работы, он запускается для некоторых строк файла и останавливается на середине xxx, а затем ничего не происходит. У меня мало компьютерных знаний. Я прочитал учебник по JavaScript в течение нескольких дней, чтобы я мог понять его структуру, а затем попытался заглянуть в код, чтобы увидеть, что происходит, но все же я не понимаю, почему код не работает как Я хочу.
Код не принадлежит мне. Он создан каким-то программистом в сети, и когда я дошел до кода, он не работал с форматом файла. Я был в состоянии настроить некоторые переменные, чтобы заставить вещь работать, но все же это остановилось в середине вещи ххх. Как я могу узнать, что не так?
Вот код скриптов.
// ==UserScript==
// @name IMDB List Importer
// @namespace Neinei0k_imdb
// @include https://www.imdb.com/list/*
// @include http://*imdb.com/list/*/edit
// @include http://*imdb.com/list/*/edit?*
// @include https://*imdb.com/list/*/edit
// @include https://*imdb.com/list/*/edit?*
// @include *
// @version 7.0
// @grant GM.xmlHttpRequest
// @description Import list of titles or people 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]; // DOM element with messages for the user.
var checkboxes = e.querySelectorAll('input[type="checkbox"]');
this.source = checkboxes[0];
this.csv = checkboxes[1];
this.unique = checkboxes[2];
var hidden_element = document.querySelector('#main > input'); // Unknown hidden element. Data needs to be send with all requests.
if (hidden_element == null) {
this.log('e','Hidden element not found');
} else {
this.hidden_data = hidden_element.id + "=" + hidden_element.value;
}
},
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 = "";
switch (level) {
case 'i': l = "Info: "; break;
case 'w': l = "Warning: "; break;
case 'e': l = "Error: "; break;
}
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.querySelector('[data-type="Characters"]') !== null) {
this.log("i", "List type: characters");
re = "ch";
} else*/
if (document.querySelector('[data-type="People"]') !== null) {
this.log("i", "List type: people");
re = "nm";
} else if (document.querySelector('[data-type="Titles"]') !== null) {
this.log("i", "List type: titles");
re = "tt";
} else {
this.log("e","Could not determine type of the list");
return [];
}
re += "[0-9]{5,10}";
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 = [];
// Parse csv
var text = this.text.split('\r\n'); // Separate by lines
this.text = null; // Variable may have lots of data which is no longer needed
var parsed_text = [];
for (var i in text) { // For each line
if (text[i].trim().length === 0) { // Ignore empty lines including lines with only white space characters
continue;
}
var state = 0; // 0 - outside of double quotes (comma character is the separator), 1 - inside double quotes (comma character is part of a field)
var parsed_line = [""];
for (var j in text[i]) {
if (state == 0 && text[i][j] == ',') {
parsed_line.push("");
} else if (text[i][j] == '"') {
state = (state + 1) % 2;
} else {
parsed_line[parsed_line.length-1] += text[i][j];
}
}
parsed_text.push(parsed_line);
}
text = parsed_text;
// console.log(text); // print parsed data
// Find const and description field numbers.
try {
if (text.length < 2) { // There must be at least 2 rows in the data
throw "No data";
}
var fl = text[0];
var fll = fl.length;
var const_field = fl.indexOf('const');
if (const_field === -1) {
const_field = fl.indexOf('Const');
if (const_field === -1) {
throw "Field 'const' not found.";
}
}
} catch (err) {
this.log("e","Input line 1: " + err);
return [];
}
var desc_field = fl.indexOf('description');
if (desc_field === -1) {
desc_field = fl.indexOf('Description');
}
this.log("i","Found csv file fields const(" + const_field +
") and description(" + desc_field + ")");
text.shift();
// Add elements to the list
for (i = 0; i < text.length; i++) {
if (text[i].length === 0)
continue;
try {
fl = 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: (desc_field == -1 ? "" : fl[desc_field])});
}
// console.log(list); // Print final list
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, 'https://www.imdb.com/list/' + l.list_id + '/' + l.list[l.ready].const + '/add', this.hidden_data);
},
send_request: function(f,l,u,d) {
GM.xmlHttpRequest({
method: "POST",
url: u,
data: d,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
onreadystatechange: f.bind(this,l)
});
/*var x = new XMLHttpRequest();
x.onreadystatechange = f.bind(this,l);
x.open('POST', u, true);
x.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');
x.send(d);*/
},
check_item: function(l, e) {
this.log("i","Add element(" + l.list[l.ready].const +
") request: readyState(" + e.readyState +
"), status(" + e.status + ")");
if (e.readyState == 4 && e.status == 200) {
if (l.list[l.ready].description.length !== 0) {
this.send_request(this.check_item_desc, l, 'https://www.imdb.com/list/' + l.list_id + '/edit/itemdescription',
'newDescription=' + l.list[l.ready].description +
'&listItem=' + JSON.parse(e.responseText).list_item_id + '&' + this.hidden_data);
} else {
this.showReady(l);
}
}
},
check_item_desc: function(l,e) {
this.log("i","Add element(" + l.list[l.ready].const +
") description request: readyState(" + e.readyState +
"), status(" + e.status + ")");
if (e.readyState == 4 && e.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) {
alert("The job is done. You can now reload the page to see result!");
} 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; // Check support of File API
var div = document.createElement('div');
div.setAttribute('class', 'search-bar');
div.style.height = "initial"
var s = '<textarea style="background-color: white; width: 100%; height: 100px; overflow: initial"></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('.lister-search');
list_edit.appendChild(div);
А вот ссылка на файл данных.
https://drive.google.com/file/d/1zfSutdmt2SvDwgrrqOpnf0T8b0Ko8IgV/view?usp=drivesdk
Текст в файле данных выглядит следующим образом.
"Const","Description",\r\n
"tt0472033","LINK(S) ON AUDIOVAULT:\n
9 (2009):\n
http://audiovault.net/download/2787",\r\n
"tt0478087","LINK(S) ON AUDIOVAULT:\n
21 (2008):\n
http://audiovault.net/download/2746",\r\n
"tt0285331","LINK(S) ON AUDIOVAULT:\n
24 - Season 2 (2002):\n
http://audiovault.net/download/5\n
24 - Season 3 (2003):\n
http://audiovault.net/download/8920\n
24 - Season 4 (2005):\n
http://audiovault.net/download/7\n
24 - Season 5 (2006):\n
http://audiovault.net/download/8\n
24 - Season 6 (2008):\n
http://audiovault.net/download/9\n
24 - Season 7 (2009):\n
http://audiovault.net/download/10\n
24 - Season 8 (2010):\n
http://audiovault.net/download/11\n
24 Season 1 (not described):\n
http://audiovault.net/download/8919",\r\n
"tt0453562","LINK(S) ON AUDIOVAULT:\n
42 (2013):\n
http://audiovault.net/download/2768",\r\n
"tt0120577","LINK(S) ON AUDIOVAULT:\n
54 (1998):\n
http://audiovault.net/download/2776",\r\n
"tt0416449","LINK(S) ON AUDIOVAULT:\n
300 (2006):\n
http://audiovault.net/download/2761",
Каждая пара значений, разделенных запятыми, содержится в строке скрипт обрабатывает вещи таким образом. В каждом значении пары значений текст может содержать разрывы строк. Это может означать много строк текста в значении. Я заканчиваю строку пары значений символами [возврат каретки] [перевод строки] и в приведенном выше коде помечаю ее символом "\ r \ n". Эта пара символов не видна в блокноте, хотя. И если в тексте значения содержится много разрывов строк, я разбиваю его символом [перевод строки]. В тексте выше я пометил его как \ n. Этот символ также не виден в Блокноте.
Первые несколько строк данных хорошо обрабатываются сценарием, но когда он встречает 9-ю строку, он останавливает обработку. Это текст строки.
"tt4922804","LINK(S) ON AUDIOVAULT:
3% - Season 1 (Portugese Description) (2016):
http://audiovault.net/download/9148
3% - Season 2 (Portugese Description) (2018):
http://audiovault.net/download/9152",
Когда я смотрю в файл журнала Google Chrome, мне показалось, что когда он отправляет запрос на сервер для обработки строки, сервер отправляет обратно статус 400. Сервер отправляет статус 0 для всех строк перед 9-й строкой, но когда скрипт отправляет запрос на обработку строки, он получает статус 400. Хотя я не очень понимаю эти вещи. И так все остановилось.
Вот фрагмент текста журнала, когда скрипт остановил обработку строк.
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element 7: tt1190080
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt1190080) request: readyState(1), status(0)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt1190080) request: readyState(2), status(0)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt1190080) request: readyState(3), status(0)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt1190080) request: readyState(4), status(200)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt1190080) description request: readyState(1), status(0)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt1190080) description request: readyState(2), status(0)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt1190080) description request: readyState(3), status(0)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt1190080) description request: readyState(4), status(200)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element 8: tt4922804
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt4922804) request: readyState(1), status(0)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt4922804) request: readyState(2), status(0)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt4922804) request: readyState(3), status(0)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt4922804) request: readyState(4), status(200)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt4922804) description request: readyState(1), status(0)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt4922804) description request: readyState(2), status(0)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt4922804) description request: readyState(3), status(0)
userscript.html?id=05c2d50a-7d60-4131-88b9-ca8f655a1300:74 IMDB List Importer: Info: Add element(tt4922804) description request: readyState(4), status(400)
Я думаю, что-то не было включено в функцию, отправьте запрос на обработку строки, но я не совсем понимаю код в них, потому что мое понимание веб-протоколов и JavaScript вполне слабый. Кстати, это ссылка на файл журнала консоли.
https://drive.google.com/file/d/1Pfxz1fEMR9QR8AUmCcQczgfqCy7a66NP/view?usp=drivesdk