-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdouban-opener.js
195 lines (190 loc) · 11.2 KB
/
douban-opener.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// ==UserScript==
// @name Douban Opener (manual ver.)
// @namespace http://tampermonkey.net/
// @version 0.0.3
// @description 帮助将豆瓣书籍数据填充到 OpenLibrary 的表格里,提交得您自己来。
// @author You
// @match https://book.douban.com/subject/*
// @match https://openlibrary.org/books/add*
// @match https://openlibrary.org/books/OL*/edit*
// @match https://openlibrary.org/account
// @icon https://www.google.com/s2/favicons?domain=douban.com
// @grant none
// ==/UserScript==
(function() {
'use strict';
const goodReadsCSVHeader = 'Book Id,Title,Author,Author l-f,Additional Authors,ISBN,ISBN13,My Rating,Average Rating,Publisher,Binding,Number of Pages,Year Published,Original Publication Year,Date Read,Date Added,Bookshelves,Bookshelves with positions,Exclusive Shelf,My Review,Spoiler,Private Notes,Read Count,Recommended For,Recommended By,Owned Copies,Original Purchase Date,Original Purchase Location,Condition,Condition Description,BCID';
var fromDouban;
if(window.location.host === 'book.douban.com') {
var h1 = document.querySelector('h1');
var button = document.createElement('button');
button.innerText = '导出';
button.classList.add('ll');
button.style.marginRight = '1em';
button.style.float = 'left';
button.onclick = function() {
var infoText = document.querySelector('#info').innerText;
var infoArray = Object.fromEntries(infoText.replace(
/(作者|出版社|出品方|副标题|原作名|译者|出版年|页数|定价|装帧|丛书|ISBN)\s*:/g, '\n$1:'
).split('\n').map(s => s.split(':').map(ss => ss.trim())).filter(a => a.length === 2));
var data = {
title: h1.innerText.trim(),
image: document.querySelector('#mainpic img')?.src,
...infoArray,
};
var param = encodeURIComponent(JSON.stringify(data)).replace('=', '-');
window.open('https://openlibrary.org/books/add?douban=' + param, '_blank');
};
var buttonContainer = document.querySelector('#interest_sect_level');
var afterButton = document.querySelector('#interest_sect_level>.a_stars');
if(buttonContainer) {
buttonContainer.insertBefore(button, afterButton);
} else {
h1.parentElement.insertBefore(button, h1.nextSibling);
}
} else if(window.location.host === 'openlibrary.org' && window.location.pathname.startsWith('/books/add')) {
var url = new URL(window.location);
var param = url.searchParams.get('douban');
if(param) {
var instruct = document.querySelector('.instruct');
var data = JSON.parse(decodeURIComponent(param));
fetch('https://openlibrary.org/isbn/' + data.ISBN + '.json')
.then(function(response) {
if(response.ok) {
return response.json()
}
}).then(function(json) {
if(json) {
var duplicateNotice = document.createElement('p');
duplicateNotice.innerHTML = '书目已经存在于 OpenLibrary 中:<a href="' + json.key + '">' + json.title + '</a>。';
duplicateNotice.style.color = 'red';
instruct.appendChild(duplicateNotice);
}
});
var filler = document.createElement('button');
filler.innerText = 'From Douban';
var year = data['出版年'].match(/\d{4}/)[0];
filler.onclick = function() {
document.querySelector('input#title').value = data.title;
var authors = data['作者'].split('/').map(s => s.trim());
var fillAuthorField = function() {
var authorFields = document.querySelectorAll('input.author');
authorFields[authorFields.length - 1].value = authors.shift();
if(authors.length !== 0) {
newAuthorField();
}
};
var newAuthorField = function() {
var addButtons = document.querySelectorAll('a.add');
addButtons[addButtons.length - 1].click();
setTimeout(fillAuthorField, 50);
};
fillAuthorField();
var authorNote = document.createElement('p');
authorNote.innerText = '您可能需要手动编辑作者一栏。英文作者最好使用对应的英文名字,最好使用 OpenLibrary 自动匹配功能校正名字。';
authorNote.style.color = 'darkred';
document.querySelector('.multi-input-autocomplete--author').appendChild(authorNote);
document.querySelector('input#publisher').value = data['出版社'];
document.querySelector('input#publish_date').value = year;
if(data.ISBN && data.ISBN.search(/^\d{13}$/) === 0) {
document.querySelector('input#id_value').value = data.ISBN;
document.querySelector('select#id_name').value = 'isbn_13';
}
};
fromDouban = JSON.parse(localStorage.getItem('fromDouban'));
if(fromDouban === null) { fromDouban = {}; }
if(data.ISBN) {
fromDouban[data.ISBN] = data;
} else {
fromDouban[data.title + ' - ' + data['作者'] + ' - ' + year + ' - ' + data['出版社']] = data;
}
localStorage.setItem('fromDouban', JSON.stringify(fromDouban));
instruct.appendChild(filler);
}
} else if(window.location.host === 'openlibrary.org' && window.location.pathname.startsWith('/books/OL')) {
var ISBN = document.querySelector('input[name=edition--identifiers--0--value]').value;
var afterCoverButton = document.querySelector('form#addWork #tabsAddbook');
fromDouban = JSON.parse(localStorage.getItem('fromDouban'));
if(fromDouban !== null && ISBN in fromDouban) {
var cover = document.querySelector('img.cover');
var book = fromDouban[ISBN];
console.log(book, cover.getAttribute('src'));
if(book.image && (!cover || cover.getAttribute('src') === '')) {
var coverButton = document.createElement('button');
coverButton.innerText = '上传封面';
coverButton.onclick = function() {
var path = window.location.pathname.replace(/edit$/, 'add-cover');
coverButton.innerText = '上传封面中';
var formData = new FormData();
formData.append('file', '');
formData.append('url', book.image);
formData.append('upload', 'Submit');
fetch(path, { method: 'POST', body: formData })
.then(function(request) {
if(request.ok) {
coverButton.innerText = '上传封面成功';
coverButton.disabled = true;
window.location.reload();
} else {
coverButton.innerText = '上传封面失败';
}
});
return false;
};
afterCoverButton.parentElement.insertBefore(coverButton, afterCoverButton);
}
}
var detailButton = document.createElement('button');
detailButton.innerText = '填充细节';
detailButton.onclick = function() {
var info = [];
if(book['副标题']) {
info.push('副标题:' + book['副标题']);
document.querySelector('input#edition-subtitle').value = book['副标题'];
}
if(book['页数']) {
info.push('页数:' + book['页数']);
document.querySelector('input#edition--number_of_pages').value = book['页数'];
}
if(book['译者']) {
info.push('译者:' + book['译者']);
document.querySelector('input#role-name').value = book['译者'];
document.querySelector('select#select-role').value = 'Translator';
document.querySelector('#roles button[name=add]').click();
}
detailButton.innerText = '请确认:填充了:' + info.join(', ');
return false;
};
afterCoverButton.parentElement.insertBefore(detailButton, afterCoverButton);
} else if(window.location.host === 'openlibrary.org' && window.location.pathname === '/account') {
var briefInfo = document.createElement('a');
var object = localStorage.getItem('fromDouban');
var booksWithoutISBN = [];
if(!object) { object = {}; } else { object = JSON.parse(object); }
briefInfo.innerText = 'Douban Opener 导出(GoodReads 格式)';
briefInfo.target = '_blank';
briefInfo.href = window.URL.createObjectURL(new Blob([
'\ufeff' + goodReadsCSVHeader + '\n'
+ Object.entries(object).filter(entry => {
if(entry[0].search(/^\d{13}$/) === 0) {
return true;
} else {
booksWithoutISBN.push(entry[1].title);
return false;
}
}).map(entry => ',' + entry[1].title + ',' + entry[1]['作者'] + ',,,,' + entry[0].replace(',', '') + ',,,,,,,,,,to-read,to-read (#1),to-read,,').join('\n')], { type: 'text/csv' }));
if(booksWithoutISBN.length > 0) {
var div = document.createElement('div');
div.innerText = '不含有 ISBN13 的书暂不支持导出:《' + booksWithoutISBN.join('》《') + '》';
document.querySelector('#contentBody').appendChild(div);
}
document.querySelector('#contentBody').appendChild(briefInfo);
var exportButton = document.createElement('button');
exportButton.innerText = 'Douban Opener: 清空缓存';
exportButton.onclick = function() {
localStorage.setItem('fromDouban', '{}');
return false;
};
document.querySelector('#contentBody').appendChild(exportButton);
}
})();