File size: 2,722 Bytes
f46e223 | 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 | import streamSaver from 'streamsaver'
import { Api } from 'telegram'
import { req } from './Fetcher'
import { telegramClient } from './Telegram'
export async function download(id: string): Promise<ReadableStream> {
const { data: response } = await req.get(`/files/${id}`, { params: { raw: 1, as_array: 1 } })
let cancel = false
const client = await telegramClient.connect()
const readableStream = new ReadableStream({
start(_controller: ReadableStreamDefaultController) {
},
async pull(controller: ReadableStreamDefaultController) {
let countFiles = 1
console.log('start downloading:', response.files)
const promises = response.files.map(async (file) => {
let chat: any
if (file.forward_info && file.forward_info.match(/^channel\//gi)) {
const [type, peerId, id, accessHash] = file.forward_info.split('/')
let peer: Api.InputPeerChannel | Api.InputPeerUser | Api.InputPeerChat
if (type === 'channel') {
peer = new Api.InputPeerChannel({
channelId: BigInt(peerId) as any,
accessHash: BigInt(accessHash as string) as any })
chat = await client.invoke(new Api.channels.GetMessages({
channel: peer,
id: [new Api.InputMessageID({ id: Number(id) })]
}))
}
} else {
chat = await client.invoke(new Api.messages.GetMessages({
id: [new Api.InputMessageID({ id: Number(file.message_id) })]
}))
}
const getData = async () => await client.downloadMedia(chat['messages'][0].media, {
outputFile: {
write: (chunk: Buffer) => {
if (cancel) return false
return controller.enqueue(chunk)
},
close: () => {
if (countFiles++ >= Number(response.files.length))
controller.close()
}
},
progressCallback: (received, total) => {
console.log('progress: ', (Number(received)/Number(total)*100).toFixed(2), '%')
}
})
return getData()
})
await Promise.all(promises)
},
cancel() {
cancel = true
}
}, {
size(chunk: any) {
return chunk.length
}
})
return readableStream
}
export const directDownload = async (id: string, name: string): Promise<void> => {
const fileStream = streamSaver.createWriteStream(name)
const writer = fileStream.getWriter()
const reader = (await download(id)).getReader()
const pump = () => reader.read().then(({ value, done }) => {
if (done) return writer.close()
writer.write(value)
return writer.ready.then(pump)
})
await pump()
} |