Browse Source

GramJS: Fix downloading images of uncommon (small) size

painor 5 years ago
parent
commit
a9cbf8fc23

+ 4 - 0
package.json

@@ -67,8 +67,12 @@
 =======
 =======
     "async-mutex": "^0.1.4",
+<<<<<<< HEAD
 >>>>>>> 1a0b5c54... GramJS: Fix images loading: add `async-mutex`; Fix signed LE ints; Bring back `readExactly`
     "big-integer": "latest",
+=======
+    "big-integer": "painor/BigInteger.js",
+>>>>>>> ddb2a0ed... GramJS: Fix downloading images of uncommon (small) size
     "croppie": "^2.6.4",
     "emoji-regex": "^8.0.0",
     "events": "^3.0.0",

+ 6 - 0
src/api/gramjs/client.ts

@@ -13,6 +13,7 @@ import {
 } from './connectors/auth';
 import { onGramJsUpdate } from './onGramJsUpdate';
 <<<<<<< HEAD
+<<<<<<< HEAD
 import localDb from './localDb';
 import { buildInputPeerPhotoFileLocation } from './inputHelpers';
 import { ApiFileLocation } from '../types';
@@ -23,6 +24,11 @@ import { ApiFileLocation } from '../types';
 
 GramJsLogger.getLogger().level = 'debug';
 >>>>>>> dda7e47e... Fix images loading; Various Gram JS fixes; Refactor Gram JS Logger
+=======
+import queuedDownloadMedia from './connectors/media';
+
+GramJsLogger.setLevel(DEBUG ? 'debug' : 'warn');
+>>>>>>> ddb2a0ed... GramJS: Fix downloading images of uncommon (small) size
 
 let client: TelegramClient;
 

+ 10 - 0
src/config.ts

@@ -0,0 +1,10 @@
+export const DEBUG = true;
+
+export const MEDIA_CACHE_DISABLED = true;
+export const MEDIA_CACHE_NAME = 'tt-media';
+
+export const GLOBAL_STATE_CACHE_DISABLED = false;
+export const GLOBAL_STATE_CACHE_KEY = 'tt-global-state';
+
+export const GRAMJS_SESSION_ID_KEY = 'GramJs:sessionId';
+export const TDLIB_SESSION_ID_KEY = 'TdLib:sessionId';

+ 23 - 9
src/lib/gramjs/client/TelegramClient.js

@@ -22,6 +22,12 @@ const DEFAULT_IPV6_IP = '[2001:67c:4e8:f002::a]'
 // Chunk sizes for upload.getFile must be multiples of the smallest size
 const MIN_CHUNK_SIZE = 4096
 const MAX_CHUNK_SIZE = 512 * 1024
+<<<<<<< HEAD
+=======
+const DEFAULT_CHUNK_SIZE = 64 // kb
+// All types
+const sizeTypes = ['w', 'y', 'x', 'm', 's']
+>>>>>>> ddb2a0ed... GramJS: Fix downloading images of uncommon (small) size
 
 
 class TelegramClient {
@@ -148,7 +154,7 @@ class TelegramClient {
         this._sender = new MTProtoSender(this.session.getAuthKey(), {
 >>>>>>> 42589b8b... GramJS: Add `LocalStorageSession` with keys and hashes for all DCs
             logger: this._log,
-            dcId:this.session.dcId,
+            dcId: this.session.dcId,
             retries: this._connectionRetries,
             delay: this._retryDelay,
             autoReconnect: this._autoReconnect,
@@ -221,8 +227,8 @@ class TelegramClient {
         return await this.connect()
     }
 
-    async _authKeyCallback(authKey,dcId) {
-        this.session.setAuthKey(authKey,dcId)
+    async _authKeyCallback(authKey, dcId) {
+        this.session.setAuthKey(authKey, dcId)
     }
 
     // endregion
@@ -252,8 +258,9 @@ class TelegramClient {
     async _createExportedSender(dcId, retries) {
         const dc = utils.getDC(dcId)
         const sender = new MTProtoSender(this.session.getAuthKey(dcId),
-            { logger: this._log,
-                dcId:dcId,
+            {
+                logger: this._log,
+                dcId: dcId,
                 retries: this._connectionRetries,
                 delay: this._retryDelay,
                 autoReconnect: this._autoReconnect,
@@ -526,8 +533,15 @@ class TelegramClient {
         if (!sizeType || !sizes || !sizes.length) {
             return null
         }
-
-        return sizes.find((s) => s.type === sizeType)
+        const indexOfSize = sizeTypes.indexOf(sizeType)
+        let size
+        for (let i = indexOfSize; i < sizeTypes.length; i++) {
+            size = sizes.find((s) => s.type === sizeTypes[i])
+            if (size) {
+                break
+            }
+        }
+        return size
     }
 
 
@@ -549,7 +563,8 @@ class TelegramClient {
         if (!(photo instanceof constructors.Photo)) {
             return
         }
-        const size = this._pickFileSize(photo.sizes, args.sizeType)
+        let size
+        size = this._pickFileSize(photo.sizes, args.sizeType)
         if (!size || (size instanceof constructors.PhotoSizeEmpty)) {
             return
         }
@@ -566,7 +581,6 @@ class TelegramClient {
         if (size instanceof constructors.PhotoCachedSize || size instanceof constructors.PhotoStrippedSize) {
             return this._downloadCachedPhotoSize(size)
         }
-
         return this.downloadFile(
             new constructors.InputPhotoFileLocation({
 >>>>>>> f70d85dd... Gram JS: Replace generated `tl/*` contents with runtime logic; TypeScript typings

+ 120 - 0
src/lib/gramjs/sessions/CacheApiSession.js

@@ -0,0 +1,120 @@
+const MemorySession = require('./Memory')
+const AuthKey = require('../crypto/AuthKey')
+const utils = require('../Utils')
+
+const CACHE_NAME = 'GramJs'
+const STORAGE_KEY_BASE = 'GramJs-session-'
+
+class CacheApi extends MemorySession {
+    constructor(sessionId) {
+        super()
+        this._storageKey = sessionId
+        this._authKeys = {}
+    }
+
+    async load() {
+        if (!this._storageKey) {
+            return
+        }
+
+        try {
+            const json = await fetchFromCache(this._storageKey)
+            const { mainDcId, keys, hashes } = JSON.parse(json)
+            const { ipAddress, port } = utils.getDC(mainDcId)
+
+            this.setDC(mainDcId, ipAddress, port, true)
+
+            Object.keys(keys).forEach((dcId) => {
+                if (keys[dcId] && hashes[dcId]){
+                    this._authKeys[dcId] = new AuthKey(
+                        Buffer.from(keys[dcId].data),
+                        Buffer.from(hashes[dcId].data)
+                    )
+                }
+            })
+        } catch (err) {
+            throw new Error(`Failed to retrieve or parse JSON from Cache for key ${this._storageKey}`)
+        }
+    }
+
+    setDC(dcId, serverAddress, port, skipUpdateStorage = false) {
+        this._dcId = dcId
+        this._serverAddress = serverAddress
+        this._port = port
+
+        delete this._authKeys[dcId]
+
+        if (!skipUpdateStorage) {
+            void this._updateStorage()
+        }
+    }
+
+    async save() {
+        if (!this._storageKey) {
+            this._storageKey = generateStorageKey()
+        }
+
+        await this._updateStorage()
+
+        return this._storageKey
+    }
+
+    get authKey() {
+        throw new Error('Not supported')
+    }
+
+    set authKey(value) {
+        throw new Error('Not supported')
+    }
+
+    getAuthKey(dcId = this._dcId) {
+        return this._authKeys[dcId]
+    }
+
+    setAuthKey(authKey, dcId = this._dcId) {
+        this._authKeys[dcId] = authKey
+
+        void this._updateStorage()
+    }
+
+    async _updateStorage() {
+        if (!this._storageKey) {
+            return
+        }
+
+        const sessionData = {
+            mainDcId: this._dcId,
+            keys: {},
+            hashes: {}
+        }
+
+        Object.keys(this._authKeys).map((dcId) => {
+            const authKey = this._authKeys[dcId]
+            sessionData.keys[dcId] = authKey._key
+            sessionData.hashes[dcId] = authKey._hash
+        })
+
+        await saveToCache(this._storageKey, JSON.stringify(sessionData))
+    }
+}
+
+function generateStorageKey() {
+    // Creating two sessions at the same moment is not expected nor supported.
+    return `${STORAGE_KEY_BASE}${Date.now()}`
+}
+
+async function fetchFromCache(key) {
+    const request = new Request(key)
+    const cache = await self.caches.open(CACHE_NAME)
+    const cached = await cache.match(request)
+    return cached ? cached.text() : null
+}
+
+async function saveToCache(key, data) {
+    const request = new Request(key)
+    const response = new Response(data)
+    const cache = await self.caches.open(CACHE_NAME)
+    return cache.put(request, response)
+}
+
+module.exports = CacheApi