@nger/fk-upload 1.0.32 → 1.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/entities/fk-download-task.entity.js +9 -3
  2. package/dist/fk-upload.module.js +8 -4
  3. package/dist/main.js +2 -1
  4. package/dist/mq-runner.js +5 -7
  5. package/dist/templates/add-task.d.ts +4 -2
  6. package/dist/templates/add-task.js +8 -4
  7. package/dist/templates/create-download-task.d.ts +0 -0
  8. package/dist/templates/create-download-task.js +1 -0
  9. package/dist/templates/player.d.ts +3 -0
  10. package/dist/templates/player.js +34 -0
  11. package/dist/templates/receive-shedule-task.d.ts +14 -0
  12. package/dist/templates/receive-shedule-task.js +64 -0
  13. package/dist/templates/setting.d.ts +5 -3
  14. package/dist/templates/setting.js +10 -11
  15. package/dist/templates/task-manage.d.ts +2 -5
  16. package/dist/templates/task-manage.js +10 -23
  17. package/dist/templates/task-types.d.ts +34 -0
  18. package/dist/templates/task-types.js +2 -0
  19. package/dist/templates/task.service.d.ts +0 -68
  20. package/dist/templates/task.service.js +406 -482
  21. package/dist/templates/tasks/actions.d.ts +38 -0
  22. package/dist/templates/tasks/actions.js +7 -0
  23. package/dist/templates/tasks/create-download-task.d.ts +12 -0
  24. package/dist/templates/tasks/create-download-task.js +65 -0
  25. package/dist/templates/tasks/download-task.d.ts +10 -0
  26. package/dist/templates/tasks/download-task.js +98 -0
  27. package/dist/templates/tasks/effect-task.d.ts +6 -0
  28. package/dist/templates/tasks/effect-task.js +30 -0
  29. package/dist/templates/tasks/fk.service.d.ts +26 -0
  30. package/dist/templates/tasks/fk.service.js +228 -0
  31. package/dist/templates/tasks/index.d.ts +0 -0
  32. package/dist/templates/tasks/index.js +1 -0
  33. package/dist/templates/tasks/providers.d.ts +2 -0
  34. package/dist/templates/tasks/providers.js +25 -0
  35. package/dist/templates/tasks/receive-shedule-task.d.ts +16 -0
  36. package/dist/templates/tasks/receive-shedule-task.js +66 -0
  37. package/dist/templates/tasks/schedule-task.d.ts +9 -0
  38. package/dist/templates/tasks/schedule-task.js +63 -0
  39. package/dist/templates/tasks/task.service.d.ts +10 -0
  40. package/dist/templates/tasks/task.service.js +77 -0
  41. package/dist/templates/tasks/upload-task.d.ts +6 -0
  42. package/dist/templates/tasks/upload-task.js +32 -0
  43. package/dist/templates/upload.service.d.ts +0 -12
  44. package/dist/templates/upload.service.js +0 -49
  45. package/package.json +1 -1
@@ -1,483 +1,407 @@
1
1
  "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.TaskService = void 0;
16
- const core_1 = require("@nger/core");
17
- const rabbitmq_1 = require("@nger/rabbitmq");
18
- const redis_1 = require("@nger/redis");
19
- const typeorm_1 = require("@nger/typeorm");
20
- const fs_extra_1 = require("fs-extra");
21
- const entities_1 = require("../entities");
22
- const request_1 = require("request");
23
- const rxjs_1 = require("rxjs");
24
- const ws_1 = require("@nger/ws");
25
- const md5_file_1 = __importDefault(require("md5-file"));
26
- const typeorm_2 = require("typeorm");
27
- const cids_1 = __importDefault(require("cids"));
28
- const multihashing_async_1 = __importDefault(require("multihashing-async"));
29
- const form_data_1 = __importDefault(require("form-data"));
30
- const axios_1 = __importDefault(require("axios"));
31
- const schedule_1 = require("@nger/schedule");
32
- const w7_1 = require("@nger/w7");
33
- const path_1 = require("path");
34
- let TaskService = class TaskService {
35
- rabbit;
36
- redis;
37
- db;
38
- ws;
39
- schedule;
40
- w7;
41
- injector;
42
- constructor(rabbit, redis, db, ws, schedule, w7, injector) {
43
- this.rabbit = rabbit;
44
- this.redis = redis;
45
- this.db = db;
46
- this.ws = ws;
47
- this.schedule = schedule;
48
- this.w7 = w7;
49
- this.injector = injector;
50
- }
51
- async addDownloadTask(task) {
52
- const content = Buffer.from(JSON.stringify(task));
53
- await this.rabbit.send('@nger/fk-upload/download-task', content);
54
- }
55
- async addUploadTask(task) {
56
- const content = Buffer.from(JSON.stringify(task));
57
- await this.rabbit.send('@nger/fk-upload/upload-task', content);
58
- }
59
- async beginUploadTask(filename) {
60
- this.redis.set(filename, `0`);
61
- }
62
- async addEffectTask(task) {
63
- // const content = Buffer.from(JSON.stringify(task));
64
- // await this.rabbit.send('@nger/fk-upload/effect-task', content)
65
- }
66
- async addScheduleTask(task) {
67
- const content = Buffer.from(JSON.stringify(task));
68
- await this.rabbit.send('@nger/fk-upload/schedule-task', content);
69
- }
70
- async createDownLoadTask(url, fkLoginId, topicId) {
71
- const hash = await (0, multihashing_async_1.default)(Buffer.from(url), 'sha1', 16);
72
- const cid = new cids_1.default(1, 'raw', hash, 'base64');
73
- let filename = encodeURIComponent(cid.toString('base64'));
74
- const _url = new URL(url);
75
- const filePath = _url.pathname;
76
- let ext = (0, path_1.extname)(filePath);
77
- filename += ext === '.' ? '.mp4' : ext;
78
- const task = new entities_1.FkDownloadTaskEntity();
79
- const root = this.injector.get(core_1.APP_ROOT);
80
- (0, fs_extra_1.ensureDirSync)((0, path_1.join)(root, 'attachments/fk-upload'));
81
- const path = (0, path_1.join)(root, 'attachments/fk-upload', filename);
82
- task.filename = filename;
83
- task.url = url;
84
- task.loginId = fkLoginId;
85
- task.totalSize = 0;
86
- task.path = path;
87
- task.status = 0;
88
- task.size = 0;
89
- task.topicId = topicId;
90
- await this.db.manager.save(task);
91
- return this.addDownloadTask(task);
92
- }
93
- async receiveScheduleTask() {
94
- const obs = await this.rabbit.receive(`@nger/fk-upload/schedule-task`);
95
- obs.subscribe({
96
- next: ([data, complete, fail]) => {
97
- const task = JSON.parse(data);
98
- this.redis.get(`setting`, (err, reply) => {
99
- if (err) {
100
- fail();
101
- }
102
- else {
103
- if (reply) {
104
- const setting = JSON.parse(reply);
105
- if (task.name === setting.name) {
106
- console.log(`shedule job regist ${task.name}`);
107
- this.schedule.scheduleJob(task.name, task.rule, async (time) => {
108
- const accounts = await this.db.manager.find(entities_1.FkLoginEntity, {});
109
- const w7Usernames = accounts.map(account => account.w7Username);
110
- const users = await this.w7.manager.find(w7_1.W7UsersEntity, { where: { username: (0, typeorm_2.In)(w7Usernames) } });
111
- const uids = users.map(user => user.uid);
112
- const uniAccounts = await this.w7.manager.find(w7_1.W7UniAccountEntity, { where: { createUid: (0, typeorm_2.In)(uids) } });
113
- const uniacids = uniAccounts.map(a => a.uniacid);
114
- const tasks = await this.db.manager.find(entities_1.FkDownloadTaskEntity, { select: ['topicId'] });
115
- const ids = tasks.map(task => task.topicId);
116
- const topics = await this.w7.manager.find(w7_1.W7ChatTopicEntity, { where: { uniacid: (0, typeorm_2.In)(uniacids), id: (0, typeorm_2.Not)((0, typeorm_2.In)(ids)) } });
117
- topics.map(topic => {
118
- if (topic.thirdUrl) {
119
- const uniacid = topic.uniacid;
120
- const account = uniAccounts.find(a => a.uniacid === uniacid);
121
- const user = users.find(u => u.uid === account.createUid);
122
- const login = accounts.find(a => a.w7Username === user.username);
123
- this.createDownLoadTask(topic.thirdUrl, login.fkLoginId, topic.id);
124
- }
125
- });
126
- });
127
- }
128
- else {
129
- complete();
130
- }
131
- }
132
- else {
133
- complete();
134
- }
135
- }
136
- });
137
- }
138
- });
139
- }
140
- async receiveEffectTask() {
141
- const obs = await this.rabbit.receive(`@nger/fk-upload/effect-task`);
142
- obs.subscribe({
143
- next: async ([data, complete, fail]) => {
144
- const task = JSON.parse(data);
145
- if (task.topicId) {
146
- this.w7.manager.update(w7_1.W7ChatTopicEntity, task.topicId, { thirdUrl: task.uploadUrl }).then(() => complete()).catch(() => fail());
147
- }
148
- else {
149
- complete();
150
- }
151
- }
152
- });
153
- }
154
- async receiveUploadTask() {
155
- const obs = await this.rabbit.receive(`@nger/fk-upload/upload-task`);
156
- obs.subscribe({
157
- next: async ([data, complete, fail]) => {
158
- const task = JSON.parse(data);
159
- this.redis.get(task.filename, async (err, reply) => {
160
- if (err)
161
- return fail();
162
- if (reply) {
163
- const isExist = await this.db.manager.find(entities_1.FkDownloadTaskEntity, { where: { filename: task.filename } });
164
- if (!isExist) {
165
- return complete();
166
- }
167
- const taskIndex = Number(reply); // next
168
- const isComplete = task.complete && task.index === taskIndex;
169
- const isShouldRunning = isComplete || (!isComplete && task.index == taskIndex);
170
- if (isShouldRunning) {
171
- // should handler
172
- const fileStream = (0, fs_extra_1.createReadStream)(task.path, { start: task.start, end: task.end });
173
- const formdata = new form_data_1.default();
174
- formdata.append('ctrl', fileStream);
175
- formdata.append('isFreeVer', this.encodeURIComponent(false));
176
- formdata.append('aid', this.encodeURIComponent(task.aid));
177
- formdata.append('folderId', this.encodeURIComponent(task.folderId));
178
- formdata.append('fileName', task.filename);
179
- formdata.append(`totalSize`, this.encodeURIComponent(task.total));
180
- formdata.append(`fileMd5`, task.fileMd5);
181
- formdata.append('index', this.encodeURIComponent(task.index));
182
- formdata.append('chunkSize', this.encodeURIComponent(task.splitSize));
183
- formdata.append('totalChunks', this.encodeURIComponent(task.totalChunks));
184
- formdata.append(`complete`, this.encodeURIComponent(task.complete));
185
- const bssInfo = {
186
- fromSite: true, siteId: 0, groupId: 0, fileSizeLimit: 1024
187
- };
188
- formdata.append('bssInfo', JSON.stringify(bssInfo));
189
- const headers = formdata.getHeaders();
190
- const uploadResult = await axios_1.default.post(task.uploadUrl, formdata, {
191
- headers: {
192
- ...headers,
193
- Cookie: task.cookies
194
- }
195
- }).then(res => res.data);
196
- if (uploadResult.code === 200) {
197
- const data = uploadResult.data;
198
- this.ws.send({
199
- action: `@nger/fk-upload/uploading`,
200
- data: {
201
- uploadSize: task.end,
202
- filename: task.filename,
203
- total: task.total
204
- }
205
- });
206
- this.redis.set(task.filename, `${task.index + 1}`, (err) => {
207
- if (err)
208
- return fail();
209
- if (data) {
210
- // fullDownUrl
211
- const downUrl = data.path;
212
- if (downUrl) {
213
- const fullUrl = downUrl.startsWith('http') ? downUrl : `https:` + downUrl;
214
- axios_1.default.post(`https://smr00.vip.webportal.top/ajax/advanceUpload.jsp?cmd=_report&_TOKEN=${task.token}`, this.encodeURIComponent({
215
- type: 1,
216
- size: task.total,
217
- time: NaN,
218
- flag: true,
219
- name: task.filename
220
- }), {
221
- headers: {
222
- [`Content-Type`]: `application/x-www-form-urlencoded; charset=UTF-8`,
223
- Cookie: task.cookies
224
- }
225
- });
226
- this.redis.del(task.filename, () => {
227
- complete();
228
- });
229
- this.ws.send({
230
- action: `@nger/fk-upload/uploading`,
231
- data: {
232
- uploadSize: task.end,
233
- filename: task.filename,
234
- total: task.total,
235
- uploadUrl: fullUrl
236
- }
237
- });
238
- this.addEffectTask({
239
- filename: task.filename,
240
- uploadUrl: fullUrl,
241
- topicId: task.topicId
242
- });
243
- this.db.manager.update(entities_1.FkDownloadTaskEntity, task.filename, {
244
- status: 2,
245
- uploadUrl: fullUrl,
246
- uploadSize: task.total
247
- });
248
- }
249
- else {
250
- this.db.manager.update(entities_1.FkDownloadTaskEntity, task.filename, {
251
- uploadSize: task.end
252
- });
253
- }
254
- }
255
- else {
256
- console.log(`data is empty`, uploadResult);
257
- }
258
- });
259
- }
260
- else {
261
- fail();
262
- }
263
- }
264
- else {
265
- fail();
266
- }
267
- }
268
- else {
269
- return complete();
270
- }
271
- });
272
- }
273
- });
274
- }
275
- async receiveDownloadTask() {
276
- const obs = await this.rabbit.receive(`@nger/fk-upload/download-task`);
277
- obs.subscribe({
278
- next: async ([data, complete, fail]) => {
279
- const task = JSON.parse(data);
280
- const download = await this.db.manager.findOne(entities_1.FkDownloadTaskEntity, { where: { filename: task.filename } });
281
- if (download) {
282
- let total = 0;
283
- download.url = decodeURIComponent(download.url);
284
- this.download(download).pipe((0, rxjs_1.throttleTime)(1000), (0, rxjs_1.switchMap)(async (res) => {
285
- const size = res.size;
286
- total = res.totalSize;
287
- this.ws.send({
288
- action: `@nger/fk-upload/downloading`,
289
- data: { total, size, filename: res.filename }
290
- });
291
- await this.db.manager.update(entities_1.FkDownloadTaskEntity, download.filename, { size: size, totalSize: total });
292
- return res;
293
- })).subscribe({
294
- next: (task) => { },
295
- complete: async () => {
296
- const md5 = await (0, md5_file_1.default)(task.path);
297
- this.db.manager.update(entities_1.FkDownloadTaskEntity, download.filename, { status: 1, size: total, fileMd5: md5 }).then(async () => {
298
- this.ws.send({
299
- action: `@nger/fk-upload/downloading`,
300
- data: { total, size: total, filename: download.filename }
301
- });
302
- this.redis.del(task.filename);
303
- await this.startUploadTask(task.filename);
304
- complete();
305
- }).catch(() => fail());
306
- },
307
- error: () => {
308
- fail();
309
- }
310
- });
311
- }
312
- else {
313
- complete();
314
- }
315
- }
316
- });
317
- }
318
- getUploadInfourl(token) {
319
- return `https://${token.url}/${token.visitType}/${token.app}/advance/info?cmd=${token.cmd}&token=${token.token}`;
320
- }
321
- encodeURIComponent(data) {
322
- if ((0, core_1.isPrimitive)(data)) {
323
- return encodeURIComponent(data);
324
- }
325
- return Object.keys(data).map(key => {
326
- const value = Reflect.get(data, key);
327
- return `${key}=${encodeURIComponent(value)}`;
328
- }).join('&');
329
- }
330
- getUploadUrl(token, forceDirect = true) {
331
- if (forceDirect) {
332
- return `https://${token.url}/${token.visitType}/${token.app}/upload?cmd=${token.cmd}&token=${token.token}`;
333
- }
334
- else {
335
- return `https://${token.url}/${token.visitType}/${token.app}/advance?cmd=${token.cmd}&token=${token.token}`;
336
- }
337
- }
338
- async reUploadTask() { }
339
- async startUploadTask(filename) {
340
- const task = await this.db.manager.findOne(entities_1.FkDownloadTaskEntity, { where: { filename } });
341
- if (task && task.status === 1) {
342
- const loginEntity = await this.db.manager.findOne(entities_1.FkLoginEntity, { where: { fkLoginId: task.loginId } });
343
- const cookies = await this.db.manager.find(entities_1.FkLoginCookieEntity, { where: { fkLoginId: task.loginId } });
344
- const cookie = cookies.map(cookie => `${cookie.key}=${cookie.value}`).join(';');
345
- // 00 take token
346
- const url = `https://i.vip.webportal.top/`;
347
- const iVipWebPortal = await axios_1.default.get(url, {
348
- headers: {
349
- Cookie: cookie
350
- }
351
- }).then(res => res.data);
352
- const items = iVipWebPortal.match(/<meta id='_TOKEN' value='(.*?)'\/>/);
353
- let token = ``;
354
- if (items && items.length === 2) {
355
- token = items[1];
356
- }
357
- if (token.length > 0) {
358
- // 01
359
- const url = `https://smr00.vip.webportal.top/cn/api/manage/advanceUpload/genAccessKey?_v=${new Date().getTime()}&_TOKEN=${token}`;
360
- const accessKey = await axios_1.default.get(url).then(res => res.data);
361
- if (accessKey.success) {
362
- const accessTokenString = decode(accessKey.accessKey);
363
- if (accessTokenString) {
364
- const accessToken = JSON.parse(accessTokenString);
365
- const uploadInfoUrl = this.getUploadInfourl(accessToken);
366
- const bssInfo = {
367
- fromSite: true, siteId: 0, groupId: 0, fileSizeLimit: 1024
368
- };
369
- const info = await axios_1.default.post(uploadInfoUrl, this.encodeURIComponent({
370
- fileMd5: task.fileMd5,
371
- fileSize: task.totalSize,
372
- isFreeVer: false,
373
- aid: loginEntity.aid,
374
- folderId: loginEntity.uploadGroupId,
375
- bssInfo: JSON.stringify(bssInfo),
376
- fileName: task.filename
377
- }), { headers: { cookie: cookie } }).then(res => res.data);
378
- if (info.code === 200) {
379
- const data = info.data;
380
- const { delayTime, splitSize, uploadedSize } = data;
381
- const uploadUrl = this.getUploadUrl(accessToken, false);
382
- const totalChunks = Math.ceil((task.totalSize) / splitSize);
383
- let start = uploadedSize;
384
- let index = Math.ceil(uploadedSize / splitSize);
385
- let complete = false;
386
- this.beginUploadTask(task.filename);
387
- do {
388
- const maxEndSize = start + splitSize;
389
- if (index >= totalChunks - 1 || maxEndSize >= task.totalSize) {
390
- complete = true;
391
- }
392
- const endSize = maxEndSize > task.totalSize ? task.totalSize : maxEndSize;
393
- await this.addUploadTask({
394
- filename: task.filename,
395
- path: task.path,
396
- uploadUrl: uploadUrl,
397
- cookies: cookie,
398
- aid: loginEntity?.aid || 0,
399
- folderId: loginEntity?.uploadGroupId || 0,
400
- start,
401
- end: endSize,
402
- total: task.totalSize,
403
- index,
404
- fileMd5: task.fileMd5,
405
- totalChunks: totalChunks,
406
- splitSize,
407
- complete,
408
- topicId: task.topicId,
409
- token: token
410
- });
411
- index = index + 1;
412
- start = endSize;
413
- } while (!complete);
414
- }
415
- }
416
- }
417
- }
418
- }
419
- }
420
- download(task) {
421
- return new rxjs_1.Observable((sub) => {
422
- // go on
423
- task.size = 0;
424
- let length = task.size;
425
- const writeStream = (0, fs_extra_1.createWriteStream)(task.path, { start: task.size });
426
- const req = (0, request_1.get)(task.url, {
427
- headers: {
428
- 'Content-Type': 'application/octet-stream'
429
- }
430
- });
431
- req.on('data', (buf) => {
432
- length = length + buf.length;
433
- task.size = length;
434
- writeStream.write(buf, (err) => {
435
- if (err)
436
- sub.error(err);
437
- });
438
- sub.next(task);
439
- });
440
- req.on('end', () => {
441
- sub.complete();
442
- writeStream.end();
443
- });
444
- req.on('response', (resp) => {
445
- const headers = resp.headers;
446
- task.totalSize = Number(Reflect.get(headers, 'content-length'));
447
- sub.next(task);
448
- });
449
- });
450
- }
451
- };
452
- TaskService = __decorate([
453
- (0, core_1.Injectable)(),
454
- __metadata("design:paramtypes", [rabbitmq_1.RabbitMqService,
455
- redis_1.Client,
456
- typeorm_1.Db,
457
- ws_1.WsService,
458
- schedule_1.ScheduleService,
459
- w7_1.W7DataSource,
460
- core_1.Injector])
461
- ], TaskService);
462
- exports.TaskService = TaskService;
463
- function decode(base64Str) {
464
- if (!base64Str)
465
- return;
466
- const t = base64Str.replace(/_/g, "/").replace(/-/g, "+");
467
- const f = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
468
- let l = 0;
469
- let p = 0;
470
- let h = [];
471
- do {
472
- const o = f.indexOf(t.charAt(l++));
473
- const u = f.indexOf(t.charAt(l++));
474
- const a = f.indexOf(t.charAt(l++));
475
- const c = f.indexOf(t.charAt(l++));
476
- const s = o << 18 | u << 12 | a << 6 | c;
477
- const e = s >> 16 & 255;
478
- const r = s >> 8 & 255;
479
- const n = 255 & s;
480
- h[p++] = 64 === a ? String.fromCharCode(e) : 64 === c ? String.fromCharCode(e, r) : String.fromCharCode(e, r, n);
481
- } while (l < t.length);
482
- return h.join('');
483
- }
2
+ // import { APP_ROOT, Injectable, Injector, isPrimitive } from '@nger/core';
3
+ // import { RabbitMqService } from '@nger/rabbitmq';
4
+ // import { Client } from '@nger/redis';
5
+ // import { Db } from '@nger/typeorm';
6
+ // import { createReadStream, createWriteStream, ensureDirSync, statSync } from 'fs-extra';
7
+ // import { FkDownloadTaskEntity, FkLoginCookieEntity, FkLoginEntity } from '../entities';
8
+ // import { get } from 'request'
9
+ // import { Observable, throttleTime, switchMap } from 'rxjs';
10
+ // import { WsService } from '@nger/ws';
11
+ // import md5file from 'md5-file'
12
+ // import { In, Not } from 'typeorm';
13
+ // import Cid from 'cids';
14
+ // import multihash from 'multihashing-async'
15
+ // export interface DownloadTask {
16
+ // filename: string;
17
+ // path: string;
18
+ // size: number;
19
+ // url: string;
20
+ // totalSize: number;
21
+ // }
22
+ // export interface UploadTask {
23
+ // filename: string;
24
+ // path: string;
25
+ // uploadUrl: string;
26
+ // start: number;
27
+ // end: number;
28
+ // total: number;
29
+ // cookies: string;
30
+ // aid: number;
31
+ // folderId: number;
32
+ // fileMd5: string;
33
+ // index: number;
34
+ // splitSize: number;
35
+ // totalChunks: number;
36
+ // complete: boolean;
37
+ // topicId: number;
38
+ // token: string;
39
+ // }
40
+ // import FromData from 'form-data';
41
+ // import axios from 'axios';
42
+ // import { ScheduleService } from '@nger/schedule';
43
+ // import { W7ChatTopicEntity, W7DataSource, W7UniAccountEntity, W7UsersEntity } from '@nger/w7'
44
+ // import { dirname, extname, join } from 'path';
45
+ // export interface EffectTask {
46
+ // filename: string;
47
+ // uploadUrl: string;
48
+ // topicId: number;
49
+ // }
50
+ // export interface ScheduleTask {
51
+ // name: string;
52
+ // rule: string;
53
+ // }
54
+ // @Injectable()
55
+ // export class TaskService {
56
+ // constructor(
57
+ // private rabbit: RabbitMqService,
58
+ // private redis: Client,
59
+ // private db: Db,
60
+ // private ws: WsService,
61
+ // private schedule: ScheduleService,
62
+ // private w7: W7DataSource,
63
+ // private injector: Injector
64
+ // ) { }
65
+ // async addDownloadTask(task: DownloadTask) {
66
+ // const content = Buffer.from(JSON.stringify(task));
67
+ // await this.rabbit.send('@nger/fk-upload/download-task', content)
68
+ // }
69
+ // async addUploadTask(task: UploadTask) {
70
+ // const content = Buffer.from(JSON.stringify(task));
71
+ // await this.rabbit.send('@nger/fk-upload/upload-task', content)
72
+ // }
73
+ // async beginUploadTask(filename: string) {
74
+ // this.redis.set(filename, `0`);
75
+ // }
76
+ // async addEffectTask(task: EffectTask) {
77
+ // // const content = Buffer.from(JSON.stringify(task)); // await this.rabbit.send('@nger/fk-upload/effect-task', content)
78
+ // }
79
+ // async addScheduleTask(task: ScheduleTask) {
80
+ // const content = Buffer.from(JSON.stringify(task));
81
+ // await this.rabbit.send('@nger/fk-upload/schedule-task', content)
82
+ // }
83
+ // async receiveEffectTask() {
84
+ // const obs = await this.rabbit.receive(`@nger/fk-upload/effect-task`);
85
+ // obs.subscribe({
86
+ // next: async ([data, complete, fail]) => {
87
+ // const task = JSON.parse(data) as EffectTask;
88
+ // if (task.topicId) {
89
+ // this.w7.manager.update(W7ChatTopicEntity, task.topicId, { thirdUrl: task.uploadUrl }).then(() => complete()).catch(() => fail())
90
+ // } else {
91
+ // complete();
92
+ // }
93
+ // }
94
+ // })
95
+ // }
96
+ // async receiveUploadTask() {
97
+ // const obs = await this.rabbit.receive(`@nger/fk-upload/upload-task`);
98
+ // obs.subscribe({
99
+ // next: async ([data, complete, fail]) => {
100
+ // const task = JSON.parse(data) as UploadTask;
101
+ // this.redis.get(task.filename, async (err, reply) => {
102
+ // if (err) return fail();
103
+ // if (reply) {
104
+ // const isExist = await this.db.manager.find(FkDownloadTaskEntity, { where: { filename: task.filename } });
105
+ // if (!isExist) {
106
+ // return complete();
107
+ // }
108
+ // const taskIndex = Number(reply); // next
109
+ // const isComplete = task.complete && task.index === taskIndex;
110
+ // const isShouldRunning = isComplete || (!isComplete && task.index == taskIndex);
111
+ // if (isShouldRunning) {
112
+ // // uploading
113
+ // // should handler
114
+ // const fileStream = createReadStream(task.path, { start: task.start, end: task.end, encoding: 'utf8' });
115
+ // const formdata = new FromData();
116
+ // formdata.append('ctrl', fileStream);
117
+ // formdata.append('isFreeVer', this.encodeURIComponent(false));
118
+ // formdata.append('aid', this.encodeURIComponent(task.aid));
119
+ // formdata.append('folderId', this.encodeURIComponent(task.folderId));
120
+ // formdata.append('fileName', task.filename);
121
+ // formdata.append(`totalSize`, this.encodeURIComponent(task.total));
122
+ // formdata.append(`fileMd5`, task.fileMd5);
123
+ // formdata.append('index', this.encodeURIComponent(task.index));
124
+ // formdata.append('chunkSize', this.encodeURIComponent(task.splitSize));
125
+ // formdata.append('totalChunks', this.encodeURIComponent(task.totalChunks))
126
+ // formdata.append(`complete`, this.encodeURIComponent(task.complete))
127
+ // const bssInfo = {
128
+ // fromSite: true, siteId: 0, groupId: 0, fileSizeLimit: 1024
129
+ // };
130
+ // formdata.append('bssInfo', JSON.stringify(bssInfo))
131
+ // const headers = formdata.getHeaders();
132
+ // const uploadResult = await axios.post(task.uploadUrl, formdata, {
133
+ // headers: {
134
+ // ...headers,
135
+ // Cookie: task.cookies
136
+ // }
137
+ // }).then(res => res.data).catch((e) => fail());
138
+ // if (uploadResult && uploadResult.code === 200) {
139
+ // const data = uploadResult.data;
140
+ // this.ws.send({
141
+ // action: `@nger/fk-upload/uploading`,
142
+ // data: {
143
+ // uploadSize: task.end,
144
+ // filename: task.filename,
145
+ // total: task.total
146
+ // }
147
+ // });
148
+ // this.redis.set(task.filename, `${task.index + 1}`, (err) => {
149
+ // if (err) return fail();
150
+ // if (data) {
151
+ // // fullDownUrl
152
+ // const downUrl = data.path as string;
153
+ // if (downUrl) {
154
+ // const fullUrl = downUrl.startsWith('http') ? downUrl : `https:` + downUrl;
155
+ // axios.post(`https://smr00.vip.webportal.top/ajax/advanceUpload.jsp?cmd=_report&_TOKEN=${task.token}`, this.encodeURIComponent({
156
+ // type: 1,
157
+ // size: task.total,
158
+ // time: NaN,
159
+ // flag: true,
160
+ // name: task.filename
161
+ // }), {
162
+ // headers: {
163
+ // [`Content-Type`]: `application/x-www-form-urlencoded; charset=UTF-8`,
164
+ // Cookie: task.cookies
165
+ // }
166
+ // });
167
+ // this.redis.del(task.filename, () => {
168
+ // complete()
169
+ // });
170
+ // this.ws.send({
171
+ // action: `@nger/fk-upload/uploading`,
172
+ // data: {
173
+ // uploadSize: task.end,
174
+ // filename: task.filename,
175
+ // total: task.total,
176
+ // uploadUrl: fullUrl
177
+ // }
178
+ // });
179
+ // this.addEffectTask({
180
+ // filename: task.filename,
181
+ // uploadUrl: fullUrl,
182
+ // topicId: task.topicId
183
+ // })
184
+ // this.db.manager.update(FkDownloadTaskEntity, task.filename, {
185
+ // status: 2,
186
+ // uploadUrl: fullUrl,
187
+ // uploadSize: task.total
188
+ // })
189
+ // } else {
190
+ // this.db.manager.update(FkDownloadTaskEntity, task.filename, {
191
+ // uploadSize: task.end
192
+ // })
193
+ // }
194
+ // } else {
195
+ // console.log(`data is empty`, uploadResult)
196
+ // }
197
+ // });
198
+ // } else {
199
+ // fail();
200
+ // }
201
+ // } else {
202
+ // fail();
203
+ // }
204
+ // } else {
205
+ // return complete();
206
+ // }
207
+ // })
208
+ // }
209
+ // })
210
+ // }
211
+ // async receiveDownloadTask() {
212
+ // const obs = await this.rabbit.receive(`@nger/fk-upload/download-task`);
213
+ // obs.subscribe({
214
+ // next: async ([data, complete, fail]) => {
215
+ // const task = JSON.parse(data) as DownloadTask;
216
+ // const download = await this.db.manager.findOne(FkDownloadTaskEntity, { where: { filename: task.filename } });
217
+ // if (download) {
218
+ // let total = 0;
219
+ // download.url = decodeURIComponent(download.url);
220
+ // this.download(download).pipe(
221
+ // throttleTime(1000),
222
+ // switchMap(async res => {
223
+ // const size = res.size;
224
+ // total = res.totalSize;
225
+ // this.ws.send({
226
+ // action: `@nger/fk-upload/downloading`,
227
+ // data: { total, size, filename: res.filename }
228
+ // });
229
+ // await this.db.manager.update(FkDownloadTaskEntity, download.filename, { size: size, totalSize: total })
230
+ // return res;
231
+ // })
232
+ // ).subscribe({
233
+ // next: (task) => { },
234
+ // complete: async () => {
235
+ // const md5 = await md5file(task.path);
236
+ // this.db.manager.update(FkDownloadTaskEntity, download.filename, { status: 1, size: total, fileMd5: md5 }).then(async () => {
237
+ // this.ws.send({
238
+ // action: `@nger/fk-upload/downloading`,
239
+ // data: { total, size: total, filename: download.filename }
240
+ // });
241
+ // this.redis.del(task.filename);
242
+ // await this.startUploadTask(task.filename);
243
+ // complete()
244
+ // }).catch(() => fail())
245
+ // },
246
+ // error: () => {
247
+ // fail();
248
+ // }
249
+ // })
250
+ // } else {
251
+ // complete();
252
+ // }
253
+ // }
254
+ // })
255
+ // }
256
+ // private getUploadInfourl(token: any) {
257
+ // return `https://${token.url}/${token.visitType}/${token.app}/advance/info?cmd=${token.cmd}&token=${token.token}`
258
+ // }
259
+ // private encodeURIComponent(data: any) {
260
+ // if (isPrimitive(data)) {
261
+ // return encodeURIComponent(data)
262
+ // }
263
+ // return Object.keys(data).map(key => {
264
+ // const value = Reflect.get(data, key)
265
+ // return `${key}=${encodeURIComponent(value)}`
266
+ // }).join('&')
267
+ // }
268
+ // private getUploadUrl(token: any, forceDirect: boolean = true) {
269
+ // if (forceDirect) {
270
+ // return `https://${token.url}/${token.visitType}/${token.app}/upload?cmd=${token.cmd}&token=${token.token}`
271
+ // } else {
272
+ // return `https://${token.url}/${token.visitType}/${token.app}/advance?cmd=${token.cmd}&token=${token.token}`
273
+ // }
274
+ // }
275
+ // async reUploadTask() { }
276
+ // async startUploadTask(filename: string) {
277
+ // const task = await this.db.manager.findOne(FkDownloadTaskEntity, { where: { filename } });
278
+ // if (task && task.status === 1) {
279
+ // const loginEntity = await this.db.manager.findOne(FkLoginEntity, { where: { fkLoginId: task.loginId } })
280
+ // const cookies = await this.db.manager.find(FkLoginCookieEntity, { where: { fkLoginId: task.loginId } });
281
+ // const cookie = cookies.map(cookie => `${cookie.key}=${cookie.value}`).join(';')
282
+ // // 00 take token
283
+ // const url = `https://i.vip.webportal.top/`;
284
+ // const iVipWebPortal: string = await axios.get(url, {
285
+ // headers: {
286
+ // Cookie: cookie
287
+ // }
288
+ // }).then(res => res.data);
289
+ // const items = iVipWebPortal.match(/<meta id='_TOKEN' value='(.*?)'\/>/);
290
+ // let token: string = ``;
291
+ // if (items && items.length === 2) {
292
+ // token = items[1];
293
+ // }
294
+ // if (token.length > 0) {
295
+ // // 01
296
+ // const url = `https://smr00.vip.webportal.top/cn/api/manage/advanceUpload/genAccessKey?_v=${new Date().getTime()}&_TOKEN=${token}`;
297
+ // const accessKey = await axios.get(url).then(res => res.data);
298
+ // if (accessKey.success) {
299
+ // const accessTokenString = decode(accessKey.accessKey)
300
+ // if (accessTokenString) {
301
+ // const accessToken = JSON.parse(accessTokenString);
302
+ // const uploadInfoUrl = this.getUploadInfourl(accessToken);
303
+ // const bssInfo = {
304
+ // fromSite: true, siteId: 0, groupId: 0, fileSizeLimit: 1024
305
+ // };
306
+ // const info = await axios.post(uploadInfoUrl, this.encodeURIComponent({
307
+ // fileMd5: task.fileMd5,
308
+ // fileSize: task.totalSize,
309
+ // isFreeVer: false,
310
+ // aid: loginEntity!.aid,
311
+ // folderId: loginEntity!.uploadGroupId,
312
+ // bssInfo: JSON.stringify(bssInfo),
313
+ // fileName: task.filename
314
+ // }), { headers: { cookie: cookie } }).then(res => res.data);
315
+ // if (info.code === 200) {
316
+ // const data = info.data;
317
+ // const { delayTime, splitSize, uploadedSize } = data;
318
+ // const uploadUrl = this.getUploadUrl(accessToken, false);
319
+ // const totalChunks = Math.ceil((task.totalSize) / splitSize);
320
+ // let start = uploadedSize;
321
+ // let index: number = Math.ceil(uploadedSize / splitSize);
322
+ // let complete: boolean = false;
323
+ // this.beginUploadTask(task.filename);
324
+ // do {
325
+ // const maxEndSize = start + splitSize;
326
+ // if (index >= totalChunks - 1 || maxEndSize >= task.totalSize) {
327
+ // complete = true;
328
+ // }
329
+ // const endSize = maxEndSize > task.totalSize ? task.totalSize : maxEndSize;
330
+ // await this.addUploadTask({
331
+ // filename: task.filename,
332
+ // path: task.path,
333
+ // uploadUrl: uploadUrl,
334
+ // cookies: cookie,
335
+ // aid: loginEntity?.aid || 0,
336
+ // folderId: loginEntity?.uploadGroupId || 0,
337
+ // start,
338
+ // end: endSize,
339
+ // total: task.totalSize,
340
+ // index,
341
+ // fileMd5: task.fileMd5,
342
+ // totalChunks: totalChunks,
343
+ // splitSize,
344
+ // complete,
345
+ // topicId: task.topicId,
346
+ // token: token
347
+ // });
348
+ // index = index + 1;
349
+ // start = endSize;
350
+ // } while (!complete);
351
+ // }
352
+ // }
353
+ // }
354
+ // }
355
+ // }
356
+ // }
357
+ // download(task: DownloadTask) {
358
+ // return new Observable<DownloadTask>((sub) => {
359
+ // // go on
360
+ // task.size = 0;
361
+ // let length = task.size;
362
+ // const writeStream = createWriteStream(task.path, { start: task.size });
363
+ // const req = get(task.url, {
364
+ // headers: {
365
+ // 'Content-Type': 'application/octet-stream'
366
+ // }
367
+ // });
368
+ // req.on('data', (buf) => {
369
+ // length = length + buf.length;
370
+ // task.size = length;
371
+ // writeStream.write(buf, (err: Error | undefined | null) => {
372
+ // if (err) sub.error(err)
373
+ // });
374
+ // sub.next(task);
375
+ // });
376
+ // req.on('end', () => {
377
+ // sub.complete();
378
+ // writeStream.end();
379
+ // });
380
+ // req.on('response', (resp: Response) => {
381
+ // const headers = resp.headers;
382
+ // task.totalSize = Number(Reflect.get(headers, 'content-length'))
383
+ // sub.next(task);
384
+ // })
385
+ // })
386
+ // }
387
+ // }
388
+ // function decode(base64Str: string): string | void {
389
+ // if (!base64Str) return;
390
+ // const t = base64Str.replace(/_/g, "/").replace(/-/g, "+")
391
+ // const f = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
392
+ // let l = 0;
393
+ // let p = 0;
394
+ // let h: string[] = [];
395
+ // do {
396
+ // const o = f.indexOf(t.charAt(l++))
397
+ // const u = f.indexOf(t.charAt(l++))
398
+ // const a = f.indexOf(t.charAt(l++))
399
+ // const c = f.indexOf(t.charAt(l++))
400
+ // const s = o << 18 | u << 12 | a << 6 | c;
401
+ // const e = s >> 16 & 255
402
+ // const r = s >> 8 & 255;
403
+ // const n = 255 & s;
404
+ // h[p++] = 64 === a ? String.fromCharCode(e) : 64 === c ? String.fromCharCode(e, r) : String.fromCharCode(e, r, n);
405
+ // } while (l < t.length)
406
+ // return h.join('')
407
+ // }