-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.js
291 lines (244 loc) · 9.9 KB
/
index.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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
// ==UserScript==
// @name QQ群相册批量下载
// @namespace http://lvshuncai.com
// @homepage https://github.com/ShunCai/QQ-Group-Albums-Downloader
// @version 1.1
// @description 自动点击QQ群相册的下载功能,实现所有的群相册的批量下载
// @author 芷炫
// @match https://h5.qzone.qq.com/groupphoto/index?inqq=*&groupId=*
// @match https://h5.qzone.qq.com/groupphoto/album?inqq=*&groupId=*
// @grant none
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
// 获取查询参数
var getQueryString = function(name) {
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
let r = window.location.search.substring(1).match(reg);
if (r != null) {
return decodeURI(r[2]);
};
return null;
}
// 延迟函数
var delay = milliseconds => new Promise(resolve => {
setTimeout(resolve, milliseconds);
});
// 上传相片按钮
let $uploadBtn = document.querySelector('#js_pic_upload_btn,#js-header-upload')
if (!$uploadBtn) {
return;
}
// 替换文件名称的特殊字符
const replaceFileName = name => {
return name.replace(/'|#|~|&| |!|\\|\/|:|\?|"|<|>|\*|\|/g, "_");
}
// 下载文件
const download = async(downloadBtn, albums) => {
for (let i = 0; i < albums.length; i++) {
const ablum = albums[i];
// 创建A标签
const downLink = document.createElement('a');
downLink.download = replaceFileName(ablum.title) + '.zip';
downLink.href = ablum.downloadUrl.replace('http:', 'https:');
downLink.style.display = 'none';
document.body.append(downLink);
// 模拟点击
downLink.click();
// Chrome requires the timeout
await delay(1000);
// 移除A标签
downLink.remove();
downloadBtn.innerText = '已下载' + (i + 1) + '/' + albums.length;
}
}
// 迅雷下载
const invokeThunder = async albums => {
// 迅雷下载任务
const thunderTask = [];
for (const album of albums) {
thunderTask.push({
name: replaceFileName(album.title) + '.zip',
url: album.downloadUrl
})
}
// 迅雷下载信息
const thunderInfo = {
taskGroupName: 'QQ群相册_' + getQueryString('groupId'),
hideYunPan: '0',
referer: 'https://h5.qzone.qq.com/',
tasks: thunderTask
}
await copyToClipboard('thunderx://' + JSON.stringify(thunderInfo));
}
// 复制文本到剪切板
const copyToClipboard = async text => {
// 创建text area
let textArea = document.createElement("textarea");
textArea.value = text;
// 使text area不在viewport,同时设置不可见
textArea.style.position = "absolute";
textArea.style.opacity = 0;
textArea.style.left = "-999999px";
textArea.style.top = "-999999px";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
// 执行复制命令并移除文本框
let res = document.execCommand('copy');
if (res) {
// Chrome requires the timeout
await delay(1000);
textArea.remove();
}
}
// 复制相册下载地址
const copyAlbumUrls = async albums => {
const urls = [];
for (const album of albums) {
urls.push(album.downloadUrl);
}
await copyToClipboard(urls.join('\n'));
}
// 获取下载URL
var getDownloadUrl = async album => {
// 请求地址参数
const urlParmas = new URLSearchParams();
urlParmas.append('g_tk', PSY.user.token());
urlParmas.append('qzonetoken', window.g_qzonetoken);
// 请求实体参数
const bodyParmas = new URLSearchParams();
bodyParmas.append('uin', PSY.user.getLoginUin());
bodyParmas.append('hostUin', -1);
bodyParmas.append('inCharset', 'utf-8');
bodyParmas.append('outCharset', 'utf-8');
bodyParmas.append('refer', 'refer');
bodyParmas.append('source', 'qzone');
bodyParmas.append('platform', 'qzone');
bodyParmas.append('format', 'json');
bodyParmas.append('appid', 422);
bodyParmas.append('selectMode', 1);
bodyParmas.append('albumid', album.id);
bodyParmas.append('hostid', getQueryString('groupId'));
bodyParmas.append('albumName', album.title);
const response = await fetch('https://h5.qzone.qq.com/proxy/domain/app.photo.qq.com/cgi-bin/app/cgi_arch_photo_v2?' + urlParmas.toString(), {
method: 'POST',
body: bodyParmas
});
return await response.json();
}
// 相册每页条目数
const ALBUMNS_PAGE_SIZE = 1000;
// 获取相册信息
const getAlbumInfo = async(page) => {
const parmas = new URLSearchParams();
parmas.append('g_tk', PSY.user.token());
parmas.append('qzonetoken', window.g_qzonetoken);
parmas.append('qunId', getQueryString('groupId'));
parmas.append('uin', PSY.user.getLoginUin());
parmas.append('start', page * ALBUMNS_PAGE_SIZE);
parmas.append('num', ALBUMNS_PAGE_SIZE);
parmas.append('format', 'json');
parmas.append('inCharset', 'utf-8');
parmas.append('outCharset', 'utf-8');
parmas.append('platform', 'qzone');
parmas.append('source', 'qzone');
parmas.append('cmd', 'qunGetAlbumList');
const response = await fetch('https://h5.qzone.qq.com/proxy/domain/u.photo.qzone.qq.com/cgi-bin/upp/qun_list_album_v2?' + parmas.toString());
return await response.json();
}
// 获取相册信息
const getAlbumList = async() => {
window.albums = [];
// 获取第一页相册
const albumInfo = await getAlbumInfo(0);
window.albums.push(...albumInfo.data.album || []);
// 相册个数
const total = albumInfo.data.total;
if (total > ALBUMNS_PAGE_SIZE) {
for (let page = 1; page * ALBUMNS_PAGE_SIZE < total; page++) {
const pageAlbumInfo = await getAlbumInfo(page);
window.albums.push(...pageAlbumInfo.data.album || []);
await delay(1500);
}
}
return window.albums;
}
// 获取相册下载链接
const getDownloadLinks = async albums => {
for (const album of albums) {
// 获取相册下载地址
const downloadInfo = await getDownloadUrl(album);
album.downloadUrl = downloadInfo.data.downloadUrl;
// 延迟
await delay(1000);
}
}
// 批量下载
const $downloadBtn = document.createElement('a');
$downloadBtn.innerText = '批量下载';
$downloadBtn.setAttribute('class', 'mod-btn-upload');
$downloadBtn.setAttribute('title', '直接通过浏览器自身下载全部相册,相册过多时,下载容易出错,建议自行复制链接到第三方工具下载');
$downloadBtn.style.cssText = "background-color: #dd905b;border-color: #dd905b;margin-left: 10px;";
$downloadBtn.addEventListener("click", async function() {
// 获取相册列表
if (!window.albums) {
this.innerText = '正在读取相册下载链接...';
window.albums = await getAlbumList();
await getDownloadLinks(window.albums);
}
this.innerText = '正在下载';
// 浏览器下载
await download(this, albums);
this.innerText = '下载完成';
setTimeout(() => {
this.innerText = '批量下载';
}, 3000);
})
$uploadBtn.parentElement.appendChild($downloadBtn);
// 迅雷下载
const $thunderBtn = document.createElement('a');
$thunderBtn.innerText = '迅雷下载';
$thunderBtn.setAttribute('title', '需先安装迅雷,并打开迅雷,以及打开剪切板监听,或直接复制链接到迅雷下载');
$thunderBtn.setAttribute('class', 'mod-btn-upload');
$thunderBtn.style.cssText = "background-color: #5b63dd;border-color: #5b63dd;margin-left: 10px;";
$thunderBtn.addEventListener("click", async function() {
// 获取相册列表
if (!window.albums) {
this.innerText = '正在读取相册下载链接...';
window.albums = await getAlbumList();
await getDownloadLinks(window.albums);
}
this.innerText = '正在触发迅雷';
// 迅雷下载
await invokeThunder(albums);
this.innerText = '已触发,若未下载,请打开迅雷后重试';
setTimeout(() => {
this.innerText = '迅雷下载';
}, 3000);
})
$uploadBtn.parentElement.appendChild($thunderBtn);
// 复制链接
const $copyLinks = document.createElement('a');
$copyLinks.innerText = '复制链接';
$copyLinks.setAttribute('title', '复制下载链接到剪切板,可以自行到迅雷、IDM等第三方工具下载,建议尽快下载,避免存在有效期');
$copyLinks.setAttribute('class', 'mod-btn-upload');
$copyLinks.style.cssText = "background-color: #5bdd6b;border-color: #5bdd6b;margin-left: 10px;";
$copyLinks.addEventListener("click", async function() {
// 获取相册列表
if (!window.albums) {
this.innerText = '正在读取相册下载链接...';
window.albums = await getAlbumList();
await getDownloadLinks(window.albums);
}
this.innerText = '正在复制';
// 复制到剪切板
await copyAlbumUrls(albums);
this.innerText = '复制完成';
setTimeout(() => {
this.innerText = '复制链接';
}, 3000);
})
$uploadBtn.parentElement.appendChild($copyLinks);
})();