瀏覽代碼

Make file size bigInt when downloading

Painor 2 年之前
父節點
當前提交
7e67fb05a8
共有 5 個文件被更改,包括 48 次插入37 次删除
  1. 10 13
      gramjs/Utils.ts
  2. 31 21
      gramjs/client/downloads.ts
  3. 2 1
      gramjs/client/uploads.ts
  4. 4 1
      gramjs/define.d.ts
  5. 1 1
      gramjs/events/NewMessage.ts

+ 10 - 13
gramjs/Utils.ts

@@ -1,4 +1,4 @@
-import type { Entity, EntityLike, FileLike, MessageIDLike } from "./define";
+import type { Entity, EntityLike, MessageIDLike } from "./define";
 import { Api } from "./tl";
 import bigInt from "big-integer";
 import * as markdown from "./extensions/markdown";
@@ -17,7 +17,7 @@ export function getFileInfo(
 ): {
     dcId?: number;
     location: Api.TypeInputFileLocation;
-    size?: number;
+    size?: bigInt.BigInteger;
 } {
     if (!fileLocation || !fileLocation.SUBCLASS_OF_ID) {
         _raiseCastFail(fileLocation, "InputFileLocation");
@@ -59,8 +59,10 @@ export function getFileInfo(
                 fileReference: location.fileReference,
                 thumbSize: location.sizes[location.sizes.length - 1].type,
             }),
-            size: _photoSizeByteCount(
-                location.sizes[location.sizes.length - 1]
+            size: bigInt(
+                _photoSizeByteCount(
+                    location.sizes[location.sizes.length - 1]
+                ) || 0
             ),
         };
     }
@@ -1025,21 +1027,16 @@ export function getInputMedia(
  * @param fileSize
  * @returns {Number}
  */
-export function getAppropriatedPartSize(fileSize: number) {
-    if (fileSize <= 104857600) {
+export function getAppropriatedPartSize(fileSize: bigInt.BigInteger) {
+    if (fileSize.lesser(104857600)) {
         // 100MB
         return 128;
     }
-    if (fileSize <= 786432000) {
+    if (fileSize.lesser(786432000)) {
         // 750MB
         return 256;
     }
-    if (fileSize <= 2097152000) {
-        // 2000MB
-        return 512;
-    }
-
-    throw new Error("File size too large");
+    return 512;
 }
 
 export function getPeer(peer: EntityLike | any) {

+ 31 - 21
gramjs/client/downloads.ts

@@ -11,6 +11,7 @@ import { createWriteStream } from "./fs";
 import { BinaryWriter } from "../extensions";
 import * as fs from "./fs";
 import path from "./path";
+import bigInt from "big-integer";
 
 /**
  * progress callback that will be called each time a new chunk is downloaded.
@@ -18,9 +19,9 @@ import path from "./path";
 export interface progressCallback {
     (
         /** How much was downloaded */
-        downloaded: number,
+        downloaded: bigInt.BigInteger,
         /** Full size of the file to be downloaded */
-        fullSize: number,
+        fullSize: bigInt.BigInteger,
         /** other args to be passed if needed */
         ...args: any[]
     ): void;
@@ -68,7 +69,7 @@ export interface DownloadFileParamsV2 {
     dcId?: number;
     /** The file size that is about to be downloaded, if known.<br/>
      Only used if ``progressCallback`` is specified. */
-    fileSize?: number;
+    fileSize?: bigInt.BigInteger;
     /** How much to download in each chunk. The larger the less requests to be made. (max is 512kb). */
     partSizeKb?: number;
     /** Progress callback accepting one param. (progress :number) which is a float between 0 and 1 */
@@ -106,7 +107,7 @@ const MAX_CHUNK_SIZE = 512 * 1024;
 export interface DirectDownloadIterInterface {
     fileLocation: Api.TypeInputFileLocation;
     dcId: number;
-    offset: number;
+    offset: bigInt.BigInteger;
     stride: number;
     chunkSize: number;
     requestSize: number;
@@ -116,12 +117,12 @@ export interface DirectDownloadIterInterface {
 
 export interface IterDownloadFunction {
     file?: Api.TypeMessageMedia | Api.TypeInputFile | Api.TypeInputFileLocation;
-    offset?: number;
+    offset?: bigInt.BigInteger;
     stride?: number;
     limit?: number;
     chunkSize?: number;
     requestSize: number;
-    fileSize?: number;
+    fileSize?: bigInt.BigInteger;
     dcId?: number;
     msgData?: [EntityLike, number];
 }
@@ -170,7 +171,7 @@ class DirectDownloadIter extends RequestIter {
             await this.close();
             return true;
         } else {
-            this.request!.offset += this._stride!;
+            this.request!.offset = this.request!.offset.add(this._stride!);
         }
     }
 
@@ -230,16 +231,20 @@ class GenericDownloadIter extends DirectDownloadIter {
         let data = Buffer.alloc(0);
 
         //  1.1. ``bad`` is how much into the data we have we need to offset
-        const bad = this.request!.offset % this.request!.limit;
+        const bad = this.request!.offset.divide(
+            this.request!.limit
+        ).toJSNumber();
         const before = this.request!.offset;
 
         // 1.2. We have to fetch from a valid offset, so remove that bad part
-        this.request!.offset -= bad;
+        this.request!.offset = this.request!.offset.subtract(bad);
 
         let done = false;
         while (!done && data.length - bad < this._chunkSize!) {
             const current = await this._request();
-            this.request!.offset += this.request!.limit;
+            this.request!.offset = this.request!.offset.add(
+                this.request!.limit
+            );
 
             data = Buffer.concat([data, current]);
             done = current.length < this.request!.limit;
@@ -254,7 +259,7 @@ class GenericDownloadIter extends DirectDownloadIter {
             this.buffer!.push(data.slice(i, i + this._chunkSize!));
 
             // 2.2. We will yield this offset, so move to the next one
-            this.request!.offset += this._stride!;
+            this.request!.offset = this.request!.offset.add(this._stride!);
         }
 
         // 2.3. If we are in the last chunk, we will return the last partial data
@@ -270,7 +275,7 @@ class GenericDownloadIter extends DirectDownloadIter {
             //   3. Be careful with the offsets. Re-fetching a bit of data
             //   is fine, since it greatly simplifies things.
             // TODO Try to not re-fetch data
-            this.request!.offset -= this._stride!;
+            this.request!.offset = this.request!.offset.subtract(this._stride!);
         }
     }
 }
@@ -280,7 +285,7 @@ function iterDownload(
     client: TelegramClient,
     {
         file,
-        offset = 0,
+        offset = bigInt.zero,
         stride,
         limit,
         chunkSize,
@@ -307,7 +312,9 @@ function iterDownload(
     }
 
     if (limit == undefined && fileSize != undefined) {
-        limit = Math.floor((fileSize + chunkSize - 1) / chunkSize);
+        limit = Math.floor(
+            fileSize.add(chunkSize).subtract(1).divide(chunkSize).toJSNumber()
+        );
     }
     if (stride == undefined) {
         stride = chunkSize;
@@ -325,9 +332,9 @@ function iterDownload(
     let cls;
     if (
         chunkSize == requestSize &&
-        offset % MAX_CHUNK_SIZE == 0 &&
+        offset!.divide(MAX_CHUNK_SIZE).eq(bigInt.zero) &&
         stride % MIN_CHUNK_SIZE == 0 &&
-        (limit == undefined || offset % limit == 0)
+        (limit == undefined || offset!.divide(limit).eq(bigInt.zero))
     ) {
         cls = DirectDownloadIter;
         client._log.info(
@@ -415,7 +422,7 @@ export async function downloadFileV2(
     }
     const writer = getWriter(outputFile);
 
-    let downloaded = 0;
+    let downloaded = bigInt.zero;
     try {
         for await (const chunk of iterDownload(client, {
             file: inputLocation,
@@ -425,9 +432,12 @@ export async function downloadFileV2(
         })) {
             await writer.write(chunk);
             if (progressCallback) {
-                await progressCallback(downloaded, fileSize || 0);
+                await progressCallback(
+                    downloaded,
+                    bigInt(fileSize || bigInt.zero)
+                );
             }
-            downloaded += chunk.length;
+            downloaded = downloaded.add(chunk.length);
         }
         return returnWriterValue(writer);
     } finally {
@@ -617,7 +627,7 @@ export async function _downloadDocument(
         }),
         {
             outputFile: outputFile,
-            fileSize: size && "size" in size ? size.size : doc.size,
+            fileSize: size && "size" in size ? bigInt(size.size) : doc.size,
             progressCallback: progressCallback,
             msgData: msgData,
         }
@@ -800,7 +810,7 @@ export async function _downloadPhoto(
         }),
         {
             outputFile: file,
-            fileSize: fileSize,
+            fileSize: bigInt(fileSize),
             progressCallback: progressCallback,
             dcId: photo.dcId,
         }

+ 2 - 1
gramjs/client/uploads.ts

@@ -9,6 +9,7 @@ import { promises as fs } from "./fs";
 import { errors, utils } from "../index";
 import { _parseMessageText } from "./messageParse";
 import { getCommentData } from "./messages";
+import bigInt from "big-integer";
 
 interface OnProgress {
     // Float between 0 and 1.
@@ -72,7 +73,7 @@ export async function uploadFile(
     const fileId = readBigIntFromBuffer(generateRandomBytes(8), true, true);
     const isLarge = size > LARGE_FILE_THRESHOLD;
 
-    const partSize = getAppropriatedPartSize(size) * KB_TO_BYTES;
+    const partSize = getAppropriatedPartSize(bigInt(size)) * KB_TO_BYTES;
     const partCount = Math.floor((size + partSize - 1) / partSize);
     const buffer = Buffer.from(await fileToBuffer(file));
 

+ 4 - 1
gramjs/define.d.ts

@@ -63,7 +63,10 @@ type OutFile =
     | Buffer
     | WriteStream
     | { write: Function; close?: Function };
-type ProgressCallback = (total: number, downloaded: number) => void;
+type ProgressCallback = (
+    total: bigInt.BigInteger,
+    downloaded: bigInt.BigInteger
+) => void;
 type ButtonLike = Api.TypeKeyboardButton | Button;
 
 type MarkupLike =

+ 1 - 1
gramjs/events/NewMessage.ts

@@ -79,7 +79,7 @@ export class NewMessage extends EventBuilder {
     /** @hidden */
     private readonly _noCheck: boolean;
 
-    constructor(newMessageParams: NewMessageInterface) {
+    constructor(newMessageParams: NewMessageInterface = {}) {
         let {
             chats,
             func,