From 68d46fffaa0ea165808b6bcce1621de0b5a733ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20=C3=87ak=C4=B1?= Date: Thu, 17 Nov 2022 10:33:10 +0300 Subject: [PATCH 01/20] Update manual.md --- docs/docs/Installation/manual.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/docs/Installation/manual.md b/docs/docs/Installation/manual.md index b7cccfb91..fc6bedc6c 100644 --- a/docs/docs/Installation/manual.md +++ b/docs/docs/Installation/manual.md @@ -51,10 +51,11 @@ If it's succeed you don't need to follow the steps below. npm i -g yarn ``` -- Define all server variables in `./server/.env`, you can copy from `./server/.env.example` +- Define all +variables in `./api/.env`, you can copy from `./api/.env.example` ```shell - cp ./server/.env.example ./server/.env + cp ./api/.env.example ./api/.env ``` Explanation: @@ -125,7 +126,7 @@ yarn workspaces run build ```shell yarn server prisma migrate deploy -cd server && node dist/index.js +cd api && node dist/index.js ``` Done! You can now open [localhost:4000](http://localhost:4000) in your browser 🎊 @@ -141,7 +142,7 @@ yarn install # install yarn workspaces run build # build yarn server prisma migrate deploy -cd server && node dist/index.js # run +cd api && node dist/index.js # run ``` -Next, you can deploy TeleDrive with [Vercel](/docs/deployment/vercel) or [PM2](/docs/deployment/pm2). \ No newline at end of file +Next, you can deploy TeleDrive with [Vercel](/docs/deployment/vercel) or [PM2](/docs/deployment/pm2). From 601c44e1cbc4250be13ca0d97cc9947851581ea5 Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Fri, 24 Mar 2023 16:47:14 -0500 Subject: [PATCH 02/20] Fix Files Download Fixing these issues #416 , #371 , #386 --- api/src/api/v1/Files.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/api/src/api/v1/Files.ts b/api/src/api/v1/Files.ts index d3d3aae8c..2edd7175b 100644 --- a/api/src/api/v1/Files.ts +++ b/api/src/api/v1/Files.ts @@ -1065,15 +1065,16 @@ export class Files { const getSizes = ({ size, sizes }) => sizes ? sizes.pop() : size const size = file.media.photo ? getSizes(file.media.photo.sizes.pop()) : file.media.document?.size - let type = file.media.photo || mimeType.match(/^image/gi) ? 'image' : null + let type = file.media.photo if (file.media.document?.mimeType.match(/^video/gi) || name.match(/\.mp4$/gi) || name.match(/\.mkv$/gi) || name.match(/\.mov$/gi)) { type = 'video' } else if (file.media.document?.mimeType.match(/pdf$/gi) || name.match(/\.doc$/gi) || name.match(/\.docx$/gi) || name.match(/\.xls$/gi) || name.match(/\.xlsx$/gi)) { type = 'document' } else if (file.media.document?.mimeType.match(/audio$/gi) || name.match(/\.mp3$/gi) || name.match(/\.ogg$/gi)) { type = 'audio' + } else if (file.media.document?.mimeType.match(/^image/gi) || name.match(/\.jpg$/gi) || name.match(/\.jpeg$/gi) || name.match(/\.png$/gi) || name.match(/\.gif$/gi)) { + type = 'image' } - return { name, message_id: file.id.toString(), @@ -1200,7 +1201,7 @@ export class Files { const end = ranges[1] ? ranges[1] : totalFileSize.toJSNumber() - 1 const readStream = createReadStream(filename(), { start, end }) - res.writeHead(206, { + res.writeHead(200, { 'Cache-Control': 'public, max-age=604800', 'ETag': Buffer.from(`${files[0].id}:${files[0].message_id}`).toString('base64'), 'Content-Range': `bytes ${start}-${end}/${totalFileSize}`, @@ -1211,7 +1212,7 @@ export class Files { }) readStream.pipe(res) } else { - res.writeHead(206, { + res.writeHead(200, { 'Cache-Control': 'public, max-age=604800', 'ETag': Buffer.from(`${files[0].id}:${files[0].message_id}`).toString('base64'), 'Content-Range': `bytes */${totalFileSize}`, From 327971db6f6e412ceaeccc3c3ca701df1cbb0df8 Mon Sep 17 00:00:00 2001 From: WitherTick <87392380+WitherTick@users.noreply.github.com> Date: Mon, 27 Mar 2023 15:27:16 +0200 Subject: [PATCH 03/20] fix: modify file naming pattern When copying a file, a "(number of duplicates)" is added at the end of its name if any file with the same name already exists in the same folder. --- api/src/api/v1/Files.ts | 26 ++++++++++++++------------ web/src/pages/dashboard/index.tsx | 3 +-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/api/src/api/v1/Files.ts b/api/src/api/v1/Files.ts index d3d3aae8c..0210c2909 100644 --- a/api/src/api/v1/Files.ts +++ b/api/src/api/v1/Files.ts @@ -307,17 +307,19 @@ export class Files { const files = await prisma.files.findMany({ where: { AND: [ - { - name: { - startsWith: body.name.replace(/\.part0*\d+$/, '') - } - }, - { - user_id: req.user?.id - }, - { - parent_id: source.parent_id - }, + { name: source.name.endsWith('.part001') ? { startsWith: source.name.replace(/\.part0*\d+$/, '.part') } : source.name }, + { user_id: req.user?.id }, + { parent_id: source.parent_id }, + ] + } + }) + + const countExists = await prisma.files.count({ + where: { + AND: [ + { name: source.name.endsWith('.part001') ? { startsWith: source.name.replace(/\.part0*\d+$/, ''), endsWith: '.part001' } : { startsWith: source.name } }, + { user_id: req.user?.id }, + { parent_id: body.parent_id } ] } }) @@ -380,7 +382,7 @@ export class Files { const response = await prisma.files.create({ data: { ...body, - name: files.length == 1 ? body.name : body.name.replace(/\.part0*\d+$/, '')+`.part${String(countFiles + 1).padStart(3, '0')}`, + name: files.length == 1 ? body.name + `${countExists ? ` (${countExists})` : ''}` : body.name.replace(/\.part0*\d+$/, '')+`${countExists ? ` (${countExists})` : ''}`+`.part${String(countFiles + 1).padStart(3, '0')}`, ...message } }) diff --git a/web/src/pages/dashboard/index.tsx b/web/src/pages/dashboard/index.tsx index 9adb5167b..b54ce43f0 100644 --- a/web/src/pages/dashboard/index.tsx +++ b/web/src/pages/dashboard/index.tsx @@ -272,8 +272,7 @@ const Dashboard: React.FC = ({ match }) const name = `Link of ${row.name}` await req.post('/files/addFolder', { file: { ...row, name, link_id: row.id, parent_id: p?.link_id || p?.id, id: undefined } }) } else { - const name = data?.find(datum => datum.name === row.name) ? `Copy of ${row.name}` : row.name - await req.post('/files/cloneFile', { file: { ...row, name, parent_id: p?.link_id || p?.id, id: undefined } }) + await req.post('/files/cloneFile', { file: { ...row, name: row.name, parent_id: p?.link_id || p?.id, id: undefined } }) } })) } else if ((act || action) === 'cut') { From 5037c2ddd69ec1cd862306582f39ea9e25e0cf4a Mon Sep 17 00:00:00 2001 From: WitherTick <87392380+WitherTick@users.noreply.github.com> Date: Mon, 27 Mar 2023 18:12:36 +0200 Subject: [PATCH 04/20] feat: file rename and upload check This commit prevents uploading or renaming a file with the same name as a file already in the folder. Also, the confirmation button of the "rename form" is changed from "Add" to "Rename". --- web/src/pages/dashboard/components/Rename.tsx | 18 +++++++++++++----- web/src/pages/dashboard/components/Upload.tsx | 8 ++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/web/src/pages/dashboard/components/Rename.tsx b/web/src/pages/dashboard/components/Rename.tsx index 2686955dd..39ab9f892 100644 --- a/web/src/pages/dashboard/components/Rename.tsx +++ b/web/src/pages/dashboard/components/Rename.tsx @@ -25,32 +25,40 @@ const Rename: React.FC = ({ const renameFile = async () => { setLoadingRename(true) - const { name } = formRename.getFieldsValue() + const name = String(formRename.getFieldsValue().name) try { + const { data: exists } = await req.get('/files', { params: { parent_id: fileRename.parent_id, name: name } }) + if (/\.part0*\d*$/.test(name)) + throw { status: 400, body: { error: 'The file name cannot end with ".part", even if followed by digits!' } } + if (/\(\d+\).+/.test(name)) + throw { status: 400, body: { error: 'The file name cannot contain text after parentheses with digits inside!' } } + if (exists.length > 0) + throw { status: 400, body: { error: `A file/folder named "${name}" already exists!` } } + const { data: result } = await req.patch(`/files/${fileRename?.id}`, { file: { name } }) notification.success({ message: 'Success', - description: `${name} renamed successfully!` + description: `${fileRename?.name.replace(/\.part0*\d+$/, '')} renamed successfully!` }) dataSource?.[1](dataSource?.[0].map((datum: any) => datum.id === result.file.id ? { ...datum, name } : datum)) setFileRename(undefined) setLoadingRename(false) formRename.resetFields() onFinish?.() - } catch (error) { + } catch (error: any) { setLoadingRename(false) return notification.error({ message: 'Error', - description: 'Failed to rename a file. Please try again!' + description: error?.body?.error || 'Failed to rename a file. Please try again!' }) } } return setFileRename(undefined)} - okText="Add" + okText="Rename" title={Rename {fileRename?.name.replace(/\.part0*\d+$/, '')}} onOk={() => formRename.submit()} cancelButtonProps={{ shape: 'round' }} diff --git a/web/src/pages/dashboard/components/Upload.tsx b/web/src/pages/dashboard/components/Upload.tsx index d7b93aa01..107547d68 100644 --- a/web/src/pages/dashboard/components/Upload.tsx +++ b/web/src/pages/dashboard/components/Upload.tsx @@ -69,6 +69,14 @@ const Upload: React.FC = ({ dataFileList: [fileList, setFileList], parent let deleted = false try { + const { data: exists } = await req.get('/files', { params: { parent_id: parent?.id, name: file.name } }) + if (/\.part0*\d*$/.test(file.name)) + throw { status: 400, body: { error: 'The file name cannot end with ".part", even if followed by digits!' } } + if (/\(\d+\).+/.test(file.name)) + throw { status: 400, body: { error: 'The file name cannot contain text after parentheses with digits inside!' } } + if (exists.length > 0) + throw { status: 400, body: { error: `A file/folder named "${file.name}" already exists!` } } + while (filesWantToUpload.current?.findIndex(f => f.uid === file.uid) !== 0) { await new Promise(res => setTimeout(res, 1000)) } From 4ea76177646545f6b1a724a594f0d554aed364c0 Mon Sep 17 00:00:00 2001 From: WitherTick <87392380+WitherTick@users.noreply.github.com> Date: Tue, 28 Mar 2023 15:00:57 +0200 Subject: [PATCH 05/20] fix: copy file issue This commit fixes the issue of copying files that reside in a chat other than the user's default one. --- api/src/api/v1/Files.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/src/api/v1/Files.ts b/api/src/api/v1/Files.ts index 0210c2909..54e8b9f6e 100644 --- a/api/src/api/v1/Files.ts +++ b/api/src/api/v1/Files.ts @@ -330,8 +330,8 @@ export class Files { const { forward_info: forwardInfo, message_id: messageId, mime_type: mimeType } = file let peerFrom: Api.InputPeerChannel | Api.InputPeerUser | Api.InputPeerChat let peerTo: Api.InputPeerChannel | Api.InputPeerUser | Api.InputPeerChat - const [type, peerId, _id, accessHash] = forwardInfo?.split('/') ?? [] if (forwardInfo && forwardInfo.match(/^channel\//gi)) { + const [type, peerId, _id, accessHash] = forwardInfo?.split('/') ?? [] if (type === 'channel') { peerFrom = new Api.InputPeerChannel({ channelId: bigInt(peerId), @@ -345,8 +345,8 @@ export class Files { chatId: bigInt(peerId) }) } } + const [type, peerId, _, accessHash] = ((req.user.settings as Prisma.JsonObject).saved_location as string).split('/') if ((req.user.settings as Prisma.JsonObject)?.saved_location) { - const [type, peerId, _, accessHash] = ((req.user.settings as Prisma.JsonObject).saved_location as string).split('/') if (type === 'channel') { peerTo = new Api.InputPeerChannel({ channelId: bigInt(peerId), @@ -370,7 +370,7 @@ export class Files { dropAuthor: true })) as any - const newForwardInfo = forwardInfo ? `${type}/${peerId}/${chat.updates[0].id.toString()}/${accessHash}` : null + const newForwardInfo = peerTo ? `${type}/${peerId}/${chat.updates[0].id.toString()}/${accessHash}` : null const message = { size: Number(file.size), message_id: chat.updates[0].id.toString(), From 325cd5467dae6ec363d9e3735d9632fd893c46f5 Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Mon, 3 Apr 2023 19:41:19 -0500 Subject: [PATCH 06/20] Minimal upload performance optimizations --- web/src/pages/dashboard/components/Upload.tsx | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/web/src/pages/dashboard/components/Upload.tsx b/web/src/pages/dashboard/components/Upload.tsx index 107547d68..4846e643f 100644 --- a/web/src/pages/dashboard/components/Upload.tsx +++ b/web/src/pages/dashboard/components/Upload.tsx @@ -37,14 +37,16 @@ const Upload: React.FC = ({ dataFileList: [fileList, setFileList], parent await new Promise(res => setTimeout(res, 3000 * ++retry)) await cb?.() if (retry === RETRY_COUNT) { - notification.error({ message: 'Failed to upload file', description: <> - - {error?.response?.data?.error || error.message || 'Something error'} - - - {JSON.stringify(error?.response?.data || error?.data || error, null, 2)} - - }) + notification.error({ + message: 'Failed to upload file', description: <> + + {error?.response?.data?.error || error.message || 'Something error'} + + + {JSON.stringify(error?.response?.data || error?.data || error, null, 2)} + + + }) throw error } } @@ -138,14 +140,17 @@ const Upload: React.FC = ({ dataFileList: [fileList, setFileList], parent if (type === 'channel') { peer = new Api.InputPeerChannel({ channelId: BigInt(peerId) as any, - accessHash: BigInt(accessHash as string) as any }) + accessHash: BigInt(accessHash as string) as any + }) } else if (type === 'user') { peer = new Api.InputPeerUser({ userId: BigInt(peerId.toString()) as any, - accessHash: BigInt(accessHash.toString()) as any }) + accessHash: BigInt(accessHash.toString()) as any + }) } else if (type === 'chat') { peer = new Api.InputPeerChat({ - chatId: BigInt(peerId) as any }) + chatId: BigInt(peerId) as any + }) } } return await client.sendFile(peer || 'me', { @@ -212,7 +217,7 @@ const Upload: React.FC = ({ dataFileList: [fileList, setFileList], parent if (responses?.length && cancelUploading.current && file.uid === cancelUploading.current) { await Promise.all(responses.map(async response => { try { - await req.delete(`/files/${response?.file.id}`) + await req.delete(/files/${ response?.file.id }) } catch (error) { // ignore } @@ -260,9 +265,9 @@ const Upload: React.FC = ({ dataFileList: [fileList, setFileList], parent const group = 2 await uploadPart(0) - for (let i = 1; i < parts - 1; i += group) { + for (const i of Array.from(Array(parts - 1).keys()).slice(1)) { if (deleted) break - const others = Array.from(Array(i + group).keys()).slice(i, Math.min(parts - 1, i + group)) + const others = Array.from(Array(group).keys()).map(j => i + j).filter(j => j < parts - 1) await Promise.all(others.map(async j => await uploadPart(j))) } if (!deleted && parts - 1 > 0) { @@ -290,14 +295,16 @@ const Upload: React.FC = ({ dataFileList: [fileList, setFileList], parent notification.error({ key: 'fileUploadError', message: error?.response?.status || 'Something error', - ...error?.response?.data ? { description: <> - - {error?.response?.data?.error || error.message || 'Something error'} - - - {JSON.stringify(error?.response?.data || error?.data || error, null, 2)} - - } : {} + ...error?.response?.data ? { + description: <> + + {error?.response?.data?.error || error.message || 'Something error'} + + + {JSON.stringify(error?.response?.data || error?.data || error, null, 2)} + + + } : {} }) // filesWantToUpload.current = filesWantToUpload.current?.map(f => f.uid === file.uid ? { ...f, status: 'done' } : f) filesWantToUpload.current = filesWantToUpload.current?.map(f => f.uid === file.uid ? null : f).filter(Boolean) From 9b13a902f15b16dd806c46338464212c3efacbdd Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Mon, 3 Apr 2023 19:52:58 -0500 Subject: [PATCH 07/20] Update Upload.tsx --- web/src/pages/dashboard/components/Upload.tsx | 51 ++++++++----------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/web/src/pages/dashboard/components/Upload.tsx b/web/src/pages/dashboard/components/Upload.tsx index 4846e643f..107547d68 100644 --- a/web/src/pages/dashboard/components/Upload.tsx +++ b/web/src/pages/dashboard/components/Upload.tsx @@ -37,16 +37,14 @@ const Upload: React.FC = ({ dataFileList: [fileList, setFileList], parent await new Promise(res => setTimeout(res, 3000 * ++retry)) await cb?.() if (retry === RETRY_COUNT) { - notification.error({ - message: 'Failed to upload file', description: <> - - {error?.response?.data?.error || error.message || 'Something error'} - - - {JSON.stringify(error?.response?.data || error?.data || error, null, 2)} - - - }) + notification.error({ message: 'Failed to upload file', description: <> + + {error?.response?.data?.error || error.message || 'Something error'} + + + {JSON.stringify(error?.response?.data || error?.data || error, null, 2)} + + }) throw error } } @@ -140,17 +138,14 @@ const Upload: React.FC = ({ dataFileList: [fileList, setFileList], parent if (type === 'channel') { peer = new Api.InputPeerChannel({ channelId: BigInt(peerId) as any, - accessHash: BigInt(accessHash as string) as any - }) + accessHash: BigInt(accessHash as string) as any }) } else if (type === 'user') { peer = new Api.InputPeerUser({ userId: BigInt(peerId.toString()) as any, - accessHash: BigInt(accessHash.toString()) as any - }) + accessHash: BigInt(accessHash.toString()) as any }) } else if (type === 'chat') { peer = new Api.InputPeerChat({ - chatId: BigInt(peerId) as any - }) + chatId: BigInt(peerId) as any }) } } return await client.sendFile(peer || 'me', { @@ -217,7 +212,7 @@ const Upload: React.FC = ({ dataFileList: [fileList, setFileList], parent if (responses?.length && cancelUploading.current && file.uid === cancelUploading.current) { await Promise.all(responses.map(async response => { try { - await req.delete(/files/${ response?.file.id }) + await req.delete(`/files/${response?.file.id}`) } catch (error) { // ignore } @@ -265,9 +260,9 @@ const Upload: React.FC = ({ dataFileList: [fileList, setFileList], parent const group = 2 await uploadPart(0) - for (const i of Array.from(Array(parts - 1).keys()).slice(1)) { + for (let i = 1; i < parts - 1; i += group) { if (deleted) break - const others = Array.from(Array(group).keys()).map(j => i + j).filter(j => j < parts - 1) + const others = Array.from(Array(i + group).keys()).slice(i, Math.min(parts - 1, i + group)) await Promise.all(others.map(async j => await uploadPart(j))) } if (!deleted && parts - 1 > 0) { @@ -295,16 +290,14 @@ const Upload: React.FC = ({ dataFileList: [fileList, setFileList], parent notification.error({ key: 'fileUploadError', message: error?.response?.status || 'Something error', - ...error?.response?.data ? { - description: <> - - {error?.response?.data?.error || error.message || 'Something error'} - - - {JSON.stringify(error?.response?.data || error?.data || error, null, 2)} - - - } : {} + ...error?.response?.data ? { description: <> + + {error?.response?.data?.error || error.message || 'Something error'} + + + {JSON.stringify(error?.response?.data || error?.data || error, null, 2)} + + } : {} }) // filesWantToUpload.current = filesWantToUpload.current?.map(f => f.uid === file.uid ? { ...f, status: 'done' } : f) filesWantToUpload.current = filesWantToUpload.current?.map(f => f.uid === file.uid ? null : f).filter(Boolean) From ad6dae52c16b559b1544d9a10ec4353fc144e65b Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Wed, 5 Apr 2023 17:33:41 -0500 Subject: [PATCH 08/20] download efficiency --- web/src/utils/Download.ts | 105 ++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 56 deletions(-) diff --git a/web/src/utils/Download.ts b/web/src/utils/Download.ts index 13e34eafb..296203b18 100644 --- a/web/src/utils/Download.ts +++ b/web/src/utils/Download.ts @@ -2,77 +2,70 @@ import streamSaver from 'streamsaver' import { Api } from 'telegram' import { req } from './Fetcher' import { telegramClient } from './Telegram' - +async function downloadFile(client, file) { + let chat + 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) })], + }) + ) + } + return client.downloadMedia(chat['messages'][0].media, { + outputFile: { + write: (chunk: Buffer) => { + return true + }, + }, + }) +} export async function download(id: string): Promise { - const { data: response } = await req.get(`/files/${id}`, { params: { raw: 1, as_array: 1 } }) - let cancel = false + const { data: response } = await req.get(`/files/${id}`, { + params: { raw: 1, as_array: 1 }, + }) const client = await telegramClient.connect() + const filesToDownload = response.files const readableStream = new ReadableStream({ - start(_controller: ReadableStreamDefaultController) { - }, - async pull(controller: ReadableStreamDefaultController) { - let countFiles = 1 - console.log('start downloading:', response.files) - for (const file of response.files) { - 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), '%') - } - }) + async pull(controller) { + for (const [index, file] of filesToDownload.entries()) { try { - await getData() + const data = await downloadFile(client, file) + controller.enqueue(data) + if (index === filesToDownload.length - 1) { + controller.close() + } } catch (error) { - console.log(error) + console.error(error) } } }, - cancel() { - cancel = true - } - }, { - size(chunk: any) { - return chunk.length - } }) return readableStream } - export const directDownload = async (id: string, name: string): Promise => { const fileStream = streamSaver.createWriteStream(name) const writer = fileStream.getWriter() const reader = (await download(id)).getReader() - const pump = () => reader.read().then(({ value, done }) => { + const pump = async () => { + const { value, done } = await reader.read() if (done) return writer.close() - writer.write(value) - return writer.ready.then(pump) - }) + await writer.write(value) + await pump() + } await pump() } \ No newline at end of file From 5ee7936083f390e53b0e3ef10928d8394765ca75 Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Thu, 6 Apr 2023 10:09:21 -0500 Subject: [PATCH 09/20] Heroku issue fix --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 584ea95a8..4aca40e50 100644 --- a/package.json +++ b/package.json @@ -18,4 +18,7 @@ "api" ], "dependencies": {} +}, +"engines": { + "node": "18.x" } From e21a6e8eccbaddd520677f90b31529b61beea80b Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Thu, 6 Apr 2023 13:57:07 -0500 Subject: [PATCH 10/20] Heroku build fix --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 4aca40e50..35ecb40a1 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,10 @@ "author": "M Gilang Januar ", "license": "MIT", "private": true, + "engines": { + "node": "16.14.0" + }, + "scripts": { "web": "yarn workspace web", "server": "yarn workspace api", @@ -18,7 +22,4 @@ "api" ], "dependencies": {} -}, -"engines": { - "node": "18.x" } From 4b41ad6a09985b0fe5f3be3d7ee5eeace4fdfce5 Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Thu, 6 Apr 2023 14:49:38 -0500 Subject: [PATCH 11/20] Update docker-compose.yml --- docker/docker-compose.yml | 85 ++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 45 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 36b630229..d3101fc5c 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,48 +1,43 @@ -version: '3' +version: 3 -services: - teledrive: - command: bash -c "(yarn api prisma migrate deploy || yarn api prisma migrate resolve --applied 20220420012853_init) && node api/dist/index.js" - labels: - traefik.http.routers.server.rule: Host(`teledrive.localhost`) - traefik.port: 4000 - ports: - - "${PORT:-4000}:${PORT:-4000}" - expose: - - ${PORT:-4000} - build: - context: ../. - dockerfile: Dockerfile - args: - REACT_APP_TG_API_ID: ${TG_API_ID} - REACT_APP_TG_API_HASH: ${TG_API_HASH} - environment: - DATABASE_URL: postgres://postgres:${DB_PASSWORD}@db:5432/teledrive?connect_timeout=60&pool_timeout=60&socket_timeout=60 - REDIS_URI: redis://redis:6379 - env_file: - - .env - depends_on: - - db - - redis +services: + teledrive: + command: bash -c "(yarn api prisma migrate deploy || yarn api prisma migrate resolve --applied 20220420012853_init) && node api/dist/index.js" + labels: + traefik.http.routers.server.rule: Host(`teledrive.localhost`) + traefik.port: 4000 + ports: + - "${PORT:-4000}:${PORT:-4000}" + expose: + - ${PORT:-4000} + build: + context: ../. + dockerfile: Dockerfile + args: + REACT_APP_TG_API_ID: ${TG_API_ID} + REACT_APP_TG_API_HASH: ${TG_API_HASH} + environment: + DATABASE_URL: postgres://postgres:${DB_PASSWORD}@db:5432/teledrive?connect_timeout=60&pool_timeout=60&socket_timeout=60 + REDIS_URI: redis://redis:6379 + env_file: + - .env + + db: + image: postgres:13 + restart: always + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_DB: teledrive + ports: + - 5432:5432 + + redis: + image: redis:6 + restart: always + ports: + - 6379:6379 - db: - image: postgres:13 - restart: always - environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: ${DB_PASSWORD} - POSTGRES_DB: teledrive - volumes: - - teledrive_data:/var/lib/postgresql/data - - redis: - image: redis:6 - restart: always - -volumes: - teledrive_data: +volumes: + teledrive_data: driver: local - driver_opts: - o: bind - type: none - device: /var/lib/postgresql/data From 6330f3b7237f2273665f72556af8f0d44c84fb01 Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Thu, 6 Apr 2023 19:37:20 -0500 Subject: [PATCH 12/20] Revert Changes --- docker/docker-compose.yml | 85 +++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index d3101fc5c..36b630229 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,43 +1,48 @@ -version: 3 +version: '3' -services: - teledrive: - command: bash -c "(yarn api prisma migrate deploy || yarn api prisma migrate resolve --applied 20220420012853_init) && node api/dist/index.js" - labels: - traefik.http.routers.server.rule: Host(`teledrive.localhost`) - traefik.port: 4000 - ports: - - "${PORT:-4000}:${PORT:-4000}" - expose: - - ${PORT:-4000} - build: - context: ../. - dockerfile: Dockerfile - args: - REACT_APP_TG_API_ID: ${TG_API_ID} - REACT_APP_TG_API_HASH: ${TG_API_HASH} - environment: - DATABASE_URL: postgres://postgres:${DB_PASSWORD}@db:5432/teledrive?connect_timeout=60&pool_timeout=60&socket_timeout=60 - REDIS_URI: redis://redis:6379 - env_file: - - .env - - db: - image: postgres:13 - restart: always - environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: ${DB_PASSWORD} - POSTGRES_DB: teledrive - ports: - - 5432:5432 - - redis: - image: redis:6 - restart: always - ports: - - 6379:6379 +services: + teledrive: + command: bash -c "(yarn api prisma migrate deploy || yarn api prisma migrate resolve --applied 20220420012853_init) && node api/dist/index.js" + labels: + traefik.http.routers.server.rule: Host(`teledrive.localhost`) + traefik.port: 4000 + ports: + - "${PORT:-4000}:${PORT:-4000}" + expose: + - ${PORT:-4000} + build: + context: ../. + dockerfile: Dockerfile + args: + REACT_APP_TG_API_ID: ${TG_API_ID} + REACT_APP_TG_API_HASH: ${TG_API_HASH} + environment: + DATABASE_URL: postgres://postgres:${DB_PASSWORD}@db:5432/teledrive?connect_timeout=60&pool_timeout=60&socket_timeout=60 + REDIS_URI: redis://redis:6379 + env_file: + - .env + depends_on: + - db + - redis -volumes: - teledrive_data: + db: + image: postgres:13 + restart: always + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_DB: teledrive + volumes: + - teledrive_data:/var/lib/postgresql/data + + redis: + image: redis:6 + restart: always + +volumes: + teledrive_data: driver: local + driver_opts: + o: bind + type: none + device: /var/lib/postgresql/data From 992947d200ed12d27fbf4e6e1531c4d5238ac72d Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Thu, 6 Apr 2023 19:42:10 -0500 Subject: [PATCH 13/20] Add caprover install script add exe attribute to new docker install script Adding Caprover install script and also adding executable attributes to install.docker.new.sh --- install.caprover.sh | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 install.caprover.sh diff --git a/install.caprover.sh b/install.caprover.sh new file mode 100644 index 000000000..979ca29f9 --- /dev/null +++ b/install.caprover.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +set -e + +echo "Node Version: $(node -v)" +echo "Yarn Version: $(yarn -v)" + +if [ ! -f docker/.env ] +then +echo "Generating docker/.env file..." + +ENV="develop" + +echo "Preparing your keys from https://my.telegram.org/" +read -p "Enter your TG_API_ID: " TG_API_ID +read -p "Enter your TG_API_HASH: " TG_API_HASH + +echo "ENV=$ENV" > docker/.env +echo "TG_API_ID=$TG_API_ID" >> docker/.env +echo "TG_API_HASH=$TG_API_HASH" >> docker/.env +fi + +git reset --hard +git clean -f +git pull origin main + +export $(cat docker/.env | xargs) + +echo +echo "Build and deploy to CapRover..." +docker build --build-arg REACT_APP_TG_API_ID=$TG_API_ID --build-arg REACT_APP_TG_API_HASH=$TG_API_HASH -t myapp . +caprover deploy --appName myapp --imageName myapp \ No newline at end of file From c4596394d248c8bfd0fe3abe5453c19ee99c4640 Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Thu, 6 Apr 2023 20:21:51 -0500 Subject: [PATCH 14/20] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index e40f99e0c..c55884de6 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,9 @@ Or, just send us an [issue](https://github.com/mgilangjanuar/teledrive/issues) f If you're experiencing issues check this https://github.com/mgilangjanuar/teledrive/issues/373 +# Deploy to Railway (DrakeTDL's forked Teledrive repo powers the railway template.) +https://railway.app/new/template/m4m_XE?referralCode=BvMMSE + ## Folder Structure We using the monorepo structure with [yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/). From d7cfb8888d005362c4195be6571e7d2dec4ea2ce Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Thu, 6 Apr 2023 20:23:07 -0500 Subject: [PATCH 15/20] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c55884de6..89d285442 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,9 @@ Or, just send us an [issue](https://github.com/mgilangjanuar/teledrive/issues) f If you're experiencing issues check this https://github.com/mgilangjanuar/teledrive/issues/373 -# Deploy to Railway (DrakeTDL's forked Teledrive repo powers the railway template.) +# Deploy to Railway https://railway.app/new/template/m4m_XE?referralCode=BvMMSE + (DrakeTDL's forked Teledrive repo powers the railway template.) ## Folder Structure From 99142159d058c9a1cc3f4e5568dd2636a218eaed Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Thu, 6 Apr 2023 20:25:15 -0500 Subject: [PATCH 16/20] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 89d285442..35ede96f0 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Or, just send us an [issue](https://github.com/mgilangjanuar/teledrive/issues) f If you're experiencing issues check this https://github.com/mgilangjanuar/teledrive/issues/373 # Deploy to Railway -https://railway.app/new/template/m4m_XE?referralCode=BvMMSE +[![Deploy](https://railway.app/button.svg)](https://railway.app/new/template/m4m_XE?referralCode=BvMMSE) (DrakeTDL's forked Teledrive repo powers the railway template.) ## Folder Structure From ec8ee55b7b898534f3cbd01b91884d3ff1b8812d Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Thu, 6 Apr 2023 20:26:23 -0500 Subject: [PATCH 17/20] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 35ede96f0..48a086899 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,9 @@ Or, just send us an [issue](https://github.com/mgilangjanuar/teledrive/issues) f If you're experiencing issues check this https://github.com/mgilangjanuar/teledrive/issues/373 # Deploy to Railway +(DrakeTDL's forked Teledrive repo powers the railway template.) [![Deploy](https://railway.app/button.svg)](https://railway.app/new/template/m4m_XE?referralCode=BvMMSE) - (DrakeTDL's forked Teledrive repo powers the railway template.) + ## Folder Structure From 021d57343e3bcebe8c22b1049aeadd6589c8bf8f Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Thu, 6 Apr 2023 20:26:55 -0500 Subject: [PATCH 18/20] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48a086899..f3271e5b3 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,9 @@ Or, just send us an [issue](https://github.com/mgilangjanuar/teledrive/issues) f If you're experiencing issues check this https://github.com/mgilangjanuar/teledrive/issues/373 # Deploy to Railway -(DrakeTDL's forked Teledrive repo powers the railway template.) [![Deploy](https://railway.app/button.svg)](https://railway.app/new/template/m4m_XE?referralCode=BvMMSE) +(DrakeTDL's forked Teledrive repo powers the railway template.) ## Folder Structure From 0a627a1e168fb1d02aa7e4db17c71ae98b2f4769 Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Thu, 6 Apr 2023 22:55:38 -0500 Subject: [PATCH 19/20] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 35ecb40a1..bba1283b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "teledrive", - "version": "2.5.2", + "version": "2.5.4", "repository": "git@github.com:mgilangjanuar/teledrive.git", "author": "M Gilang Januar ", "license": "MIT", From 4ee54e1cf57204b195ca3731c3a356f6e9ee9a92 Mon Sep 17 00:00:00 2001 From: Bullseyecowbelly <34012548+greengeckowizard@users.noreply.github.com> Date: Thu, 6 Apr 2023 22:56:32 -0500 Subject: [PATCH 20/20] Update package.json --- api/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/package.json b/api/package.json index 05c833374..7925f6608 100644 --- a/api/package.json +++ b/api/package.json @@ -1,6 +1,6 @@ { "name": "api", - "version": "2.5.3", + "version": "2.5.4", "main": "dist/index.js", "license": "MIT", "private": true, @@ -85,4 +85,4 @@ "rimraf": "^3.0.2", "typescript": "^4.4.2" } -} \ No newline at end of file +}