From 24023560132a24d2651c33711647c52ee2ee5786 Mon Sep 17 00:00:00 2001 From: Fabian Schlenz Date: Thu, 12 Apr 2018 06:54:14 +0200 Subject: [PATCH 1/6] Added a DatabaseUpdate to convert the data to json. --- build.gradle | 3 +- .../telegram_backup/DatabaseUpdates.kt | 40 +++++++++++++++++++ .../de/fabianonline/telegram_backup/Utils.kt | 24 +++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9017a1b..34616be 100644 --- a/build.gradle +++ b/build.gradle @@ -38,7 +38,8 @@ dependencies { compile 'com.github.spullara.mustache.java:compiler:0.9.5' compile 'org.slf4j:slf4j-api:1.7.21' compile 'ch.qos.logback:logback-classic:1.1.7' - compile 'com.google.code.gson:gson:2.5' + compile 'com.google.code.gson:gson:2.8.0' + compile 'com.github.salomonbrys.kotson:kotson:2.5.0' compile 'com.github.kittinunf.fuel:fuel:1.12.0' testCompile 'junit:junit:4.12' diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt b/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt index 7ac15ba..5111c01 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt @@ -15,6 +15,8 @@ import org.slf4j.LoggerFactory import org.slf4j.Logger import de.fabianonline.telegram_backup.mediafilemanager.FileManagerFactory import de.fabianonline.telegram_backup.mediafilemanager.AbstractMediaFileManager +import com.github.salomonbrys.kotson.* +import com.google.gson.* class DatabaseUpdates(protected var conn: Connection, protected var db: Database) { @@ -33,6 +35,7 @@ class DatabaseUpdates(protected var conn: Connection, protected var db: Database register(DB_Update_8(conn, db)) register(DB_Update_9(conn, db)) register(DB_Update_10(conn, db)) + register(DB_Update_11(conn, db)) } fun doUpdates() { @@ -451,3 +454,40 @@ internal class DB_Update_10(conn: Connection, db: Database) : DatabaseUpdate(con execute("CREATE TABLE settings (key TEXT PRIMARY KEY, value TEXT)") } } + +internal class DB_Update_11(conn: Connection, db: Database) : DatabaseUpdate(conn, db) { + override val version = 11 + val logger = LoggerFactory.getLogger(DB_Update_11::class.java) + + override fun _doUpdate() { + execute("ALTER TABLE messages ADD COLUMN json TEXT NULL") + val limit = 5000 + var offset = 0 + var i = 0 + val ps = conn.prepareStatement("UPDATE messages SET json=? WHERE id=?") + do { + i = 0 + logger.debug("Querying with limit $limit and offset $offset") + val rs = db.executeQuery("SELECT id, data FROM messages WHERE json IS NULL AND api_layer=53 LIMIT $limit") + while (rs.next()) { + i++ + val id = rs.getInt(1) + val msg = Database.bytesToTLMessage(rs.getBytes(2)) + if (msg == null) continue + val json = msg.toJson() + ps.setString(1, json) + ps.setInt(2, id) + ps.addBatch() + } + rs.close() + conn.setAutoCommit(false) + ps.executeBatch() + ps.clearBatch() + conn.commit() + conn.setAutoCommit(true) + + print(".") + } while (i >= limit) + ps.close() + } +} diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt b/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt index 2381427..9a2dd17 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt @@ -17,11 +17,13 @@ package de.fabianonline.telegram_backup import com.github.badoualy.telegram.tl.exception.RpcErrorException +import com.github.badoualy.telegram.tl.api.TLMessage import java.io.File import java.util.Vector import java.util.concurrent.TimeUnit import java.util.concurrent.TimeoutException import com.google.gson.* +import com.github.salomonbrys.kotson.* import java.net.URL import org.apache.commons.io.IOUtils import de.fabianonline.telegram_backup.Version @@ -223,3 +225,25 @@ fun Any.toJson(): String = Gson().toJson(this) fun Any.toPrettyJson(): String = GsonBuilder().setPrettyPrinting().create().toJson(this) class MaxTriesExceededException(): RuntimeException("Max tries exceeded") {} + +fun TLMessage.toJson(): String { + val json = Gson().toJsonTree(this) + cleanUpMessageJson(json) + return json.toString() +} + +fun cleanUpMessageJson(json : JsonElement) { + if (json.isJsonArray) { + json.array.forEach {cleanUpMessageJson(it)} + return + } else if (!json.isJsonObject) { + return + } + if (json.obj.has("bytes")) { + json.obj -= "bytes" + return + } + json.obj.forEach {_: String, elm: JsonElement -> + if (elm.isJsonObject || elm.isJsonArray) cleanUpMessageJson(elm) + } +} From 6d4701189b40b4cc8833575bdab8f410d5e81961 Mon Sep 17 00:00:00 2001 From: Fabian Schlenz Date: Fri, 13 Apr 2018 06:10:27 +0200 Subject: [PATCH 2/6] Added json columns to users and chats tables; newly incoming objects are now saved together with their JSON data. --- .../fabianonline/telegram_backup/Database.kt | 38 ++++++++++++------- .../telegram_backup/DatabaseUpdates.kt | 2 + .../de/fabianonline/telegram_backup/Utils.kt | 4 +- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/Database.kt b/src/main/kotlin/de/fabianonline/telegram_backup/Database.kt index 8175952..4cedd26 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/Database.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/Database.kt @@ -16,6 +16,7 @@ package de.fabianonline.telegram_backup +import com.github.badoualy.telegram.api.Kotlogram import com.github.badoualy.telegram.tl.api.* import com.github.badoualy.telegram.tl.core.TLVector import com.github.badoualy.telegram.api.TelegramClient @@ -266,13 +267,10 @@ class Database constructor(val file_base: String, val user_manager: UserManager) @Synchronized fun saveMessages(all: TLVector, api_layer: Int, source_type: MessageSource = MessageSource.NORMAL, settings: Settings?) { - //"(id, dialog_id, from_id, from_type, text, time, has_media, data, sticker, type) " + - //"VALUES " + - //"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); - val columns = "(message_id, message_type, source_type, source_id, sender_id, fwd_from_id, text, time, has_media, media_type, media_file, media_size, data, api_layer) " + + val columns = "(message_id, message_type, source_type, source_id, sender_id, fwd_from_id, text, time, has_media, media_type, media_file, media_size, data, api_layer, json) " + "VALUES " + - "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" - //1 2 3 4 5 6 7 8 9 10 11 12 13 14 + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + //1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 val ps = conn.prepareStatement("INSERT OR REPLACE INTO messages " + columns) val ps_insert_or_ignore = conn.prepareStatement("INSERT OR IGNORE INTO messages " + columns) @@ -343,6 +341,7 @@ class Database constructor(val file_base: String, val user_manager: UserManager) msg.serializeBody(stream) ps.setBytes(13, stream.toByteArray()) ps.setInt(14, api_layer) + ps.setString(15, msg.toJson()) ps.addBatch() } else if (msg is TLMessageService) { ps_insert_or_ignore.setInt(1, msg.getId()) @@ -381,6 +380,7 @@ class Database constructor(val file_base: String, val user_manager: UserManager) ps_insert_or_ignore.setNull(12, Types.INTEGER) ps_insert_or_ignore.setNull(13, Types.BLOB) ps_insert_or_ignore.setInt(14, api_layer) + ps_insert_or_ignore.setString(15, msg.toJson()) ps_insert_or_ignore.addBatch() } else if (msg is TLMessageEmpty) { ps_insert_or_ignore.setInt(1, msg.getId()) @@ -397,6 +397,7 @@ class Database constructor(val file_base: String, val user_manager: UserManager) ps_insert_or_ignore.setNull(12, Types.INTEGER) ps_insert_or_ignore.setNull(13, Types.BLOB) ps_insert_or_ignore.setInt(14, api_layer) + ps_insert_or_ignore.setNull(15, Types.VARCHAR) ps_insert_or_ignore.addBatch() } else { throw RuntimeException("Unexpected Message type: " + msg.javaClass) @@ -418,18 +419,23 @@ class Database constructor(val file_base: String, val user_manager: UserManager) fun saveChats(all: TLVector) { val ps_insert_or_replace = conn.prepareStatement( "INSERT OR REPLACE INTO chats " + - "(id, name, type) " + + "(id, name, type, json, api_layer) " + "VALUES " + - "(?, ?, ?)") + "(?, ?, ?, ?, ?)") val ps_insert_or_ignore = conn.prepareStatement( "INSERT OR IGNORE INTO chats " + - "(id, name, type) " + + "(id, name, type, json, api_layer) " + "VALUES " + - "(?, ?, ?)") + "(?, ?, ?, ?, ?)") for (abs in all) { ps_insert_or_replace.setInt(1, abs.getId()) ps_insert_or_ignore.setInt(1, abs.getId()) + val json = abs.toJson() + ps_insert_or_replace.setString(4, json) + ps_insert_or_ignore.setString(4, json) + ps_insert_or_replace.setInt(5, Kotlogram.API_LAYER) + ps_insert_or_ignore.setInt(5, Kotlogram.API_LAYER) if (abs is TLChatEmpty) { ps_insert_or_ignore.setNull(2, Types.VARCHAR) ps_insert_or_ignore.setString(3, "empty_chat") @@ -470,14 +476,14 @@ class Database constructor(val file_base: String, val user_manager: UserManager) fun saveUsers(all: TLVector) { val ps_insert_or_replace = conn.prepareStatement( "INSERT OR REPLACE INTO users " + - "(id, first_name, last_name, username, type, phone) " + + "(id, first_name, last_name, username, type, phone, json, api_layer) " + "VALUES " + - "(?, ?, ?, ?, ?, ?)") + "(?, ?, ?, ?, ?, ?, ?, ?)") val ps_insert_or_ignore = conn.prepareStatement( "INSERT OR IGNORE INTO users " + - "(id, first_name, last_name, username, type, phone) " + + "(id, first_name, last_name, username, type, phone, json, api_layer) " + "VALUES " + - "(?, ?, ?, ?, ?, ?)") + "(?, ?, ?, ?, ?, ?, ?, ?)") for (abs in all) { if (abs is TLUser) { val user = abs @@ -487,6 +493,8 @@ class Database constructor(val file_base: String, val user_manager: UserManager) ps_insert_or_replace.setString(4, user.getUsername()) ps_insert_or_replace.setString(5, "user") ps_insert_or_replace.setString(6, user.getPhone()) + ps_insert_or_replace.setString(7, user.toJson()) + ps_insert_or_replace.setInt(8, Kotlogram.API_LAYER) ps_insert_or_replace.addBatch() } else if (abs is TLUserEmpty) { ps_insert_or_ignore.setInt(1, abs.getId()) @@ -495,6 +503,8 @@ class Database constructor(val file_base: String, val user_manager: UserManager) ps_insert_or_ignore.setNull(4, Types.VARCHAR) ps_insert_or_ignore.setString(5, "empty_user") ps_insert_or_ignore.setNull(6, Types.VARCHAR) + ps_insert_or_ignore.setNull(7, Types.VARCHAR) + ps_insert_or_ignore.setInt(8, Kotlogram.API_LAYER) ps_insert_or_ignore.addBatch() } else { throw RuntimeException("Unexpected " + abs.javaClass) diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt b/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt index 5111c01..e25b95f 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt @@ -461,6 +461,8 @@ internal class DB_Update_11(conn: Connection, db: Database) : DatabaseUpdate(con override fun _doUpdate() { execute("ALTER TABLE messages ADD COLUMN json TEXT NULL") + execute("ALTER TABLE chats ADD COLUMN json TEXT NULL, api_layer INTEGER NULL") + execute("ALTER TABLE users ADD COLUMN json TEXT NULL, api_layer INTEGER NULL") val limit = 5000 var offset = 0 var i = 0 diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt b/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt index 9a2dd17..4dbb574 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt @@ -17,7 +17,7 @@ package de.fabianonline.telegram_backup import com.github.badoualy.telegram.tl.exception.RpcErrorException -import com.github.badoualy.telegram.tl.api.TLMessage +import com.github.badoualy.telegram.tl.api.TLAbsMessage import java.io.File import java.util.Vector import java.util.concurrent.TimeUnit @@ -226,7 +226,7 @@ fun Any.toPrettyJson(): String = GsonBuilder().setPrettyPrinting().create().toJs class MaxTriesExceededException(): RuntimeException("Max tries exceeded") {} -fun TLMessage.toJson(): String { +fun TLAbsMessage.toJson(): String { val json = Gson().toJsonTree(this) cleanUpMessageJson(json) return json.toString() From 6b9cc9533ab07c07b260b35bc11cb84f793c4b7b Mon Sep 17 00:00:00 2001 From: Fabian Schlenz Date: Sat, 14 Apr 2018 15:01:54 +0200 Subject: [PATCH 3/6] Better status reports from the DatabaseUpdate. --- .../de/fabianonline/telegram_backup/DatabaseUpdates.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt b/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt index e25b95f..af588d8 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt @@ -463,10 +463,12 @@ internal class DB_Update_11(conn: Connection, db: Database) : DatabaseUpdate(con execute("ALTER TABLE messages ADD COLUMN json TEXT NULL") execute("ALTER TABLE chats ADD COLUMN json TEXT NULL, api_layer INTEGER NULL") execute("ALTER TABLE users ADD COLUMN json TEXT NULL, api_layer INTEGER NULL") - val limit = 5000 + val limit = 1000 var offset = 0 var i = 0 val ps = conn.prepareStatement("UPDATE messages SET json=? WHERE id=?") + println(" Updating messages to add their JSON representation to the database. This might take a few moments...") + print(" ") do { i = 0 logger.debug("Querying with limit $limit and offset $offset") @@ -490,6 +492,7 @@ internal class DB_Update_11(conn: Connection, db: Database) : DatabaseUpdate(con print(".") } while (i >= limit) + println() ps.close() } } From 6b5b9a669b99eea85061aa04346673689d82a912 Mon Sep 17 00:00:00 2001 From: Fabian Schlenz Date: Mon, 16 Apr 2018 05:57:05 +0200 Subject: [PATCH 4/6] WIP: Reworking mediafilemanagers to work with JSON. --- .../telegram_backup/DatabaseUpdates.kt | 17 +++---- .../mediafilemanager/FileManagerFactory.kt | 18 +++++-- .../mediafilemanager/PhotoFileManager.kt | 48 ++++++++++--------- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt b/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt index af588d8..ddf997a 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt @@ -461,24 +461,25 @@ internal class DB_Update_11(conn: Connection, db: Database) : DatabaseUpdate(con override fun _doUpdate() { execute("ALTER TABLE messages ADD COLUMN json TEXT NULL") - execute("ALTER TABLE chats ADD COLUMN json TEXT NULL, api_layer INTEGER NULL") - execute("ALTER TABLE users ADD COLUMN json TEXT NULL, api_layer INTEGER NULL") - val limit = 1000 + execute("ALTER TABLE chats ADD COLUMN json TEXT NULL") + execute("ALTER TABLE chats ADD COLUMN api_layer INTEGER NULL") + execute("ALTER TABLE users ADD COLUMN json TEXT NULL") + execute("ALTER TABLE users ADD COLUMN api_layer INTEGER NULL") + val limit = 5000 var offset = 0 - var i = 0 + var i: Int val ps = conn.prepareStatement("UPDATE messages SET json=? WHERE id=?") println(" Updating messages to add their JSON representation to the database. This might take a few moments...") print(" ") do { i = 0 - logger.debug("Querying with limit $limit and offset $offset") + logger.debug("Querying with limit $limit, offset is now $offset") val rs = db.executeQuery("SELECT id, data FROM messages WHERE json IS NULL AND api_layer=53 LIMIT $limit") while (rs.next()) { i++ val id = rs.getInt(1) val msg = Database.bytesToTLMessage(rs.getBytes(2)) - if (msg == null) continue - val json = msg.toJson() + val json = if (msg==null) Gson().toJson(null) else msg.toJson() ps.setString(1, json) ps.setInt(2, id) ps.addBatch() @@ -489,7 +490,7 @@ internal class DB_Update_11(conn: Connection, db: Database) : DatabaseUpdate(con ps.clearBatch() conn.commit() conn.setAutoCommit(true) - + offset += limit print(".") } while (i >= limit) println() diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/FileManagerFactory.kt b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/FileManagerFactory.kt index 8248f15..af1fd1f 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/FileManagerFactory.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/FileManagerFactory.kt @@ -38,15 +38,27 @@ import java.util.ArrayList import java.util.LinkedList import java.net.URL import java.util.concurrent.TimeoutException +import com.google.gson.* +import com.github.salomonbrys.kotson.* import org.apache.commons.io.FileUtils object FileManagerFactory { fun getFileManager(m: TLMessage?, u: UserManager, file_base: String, settings: Settings?): AbstractMediaFileManager? { if (m == null) return null - val media = m.getMedia() ?: return null + val json = Gson().toJsonTree(m).obj + return getFileManager(json, u, file_base, settings) + } + + fun getFileManager(m: JsonObject?, u: UserManager, file_base: String, settings: Settings?): AbstractMediaFileManager? { + if (m == null) return null + val media = m.get("media")?.obj ?: return null + + if (media.contains("photo")) { + return PhotoFileManager(media["photo"].obj, u, file_base) + } - if (media is TLMessageMediaPhoto) { + /*if (media is TLMessageMediaPhoto) { return PhotoFileManager(m, u, file_base) } else if (media is TLMessageMediaDocument) { val d = DocumentFileManager(m, u, file_base) @@ -67,7 +79,7 @@ object FileManagerFactory { return UnsupportedFileManager(m, u, file_base, "venue") } else { AbstractMediaFileManager.throwUnexpectedObjectError(media) - } + }*/ return null } } diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/PhotoFileManager.kt b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/PhotoFileManager.kt index 8421398..068c6d2 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/PhotoFileManager.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/PhotoFileManager.kt @@ -25,45 +25,47 @@ import com.github.badoualy.telegram.tl.exception.RpcErrorException import java.io.IOException import java.util.concurrent.TimeoutException -class PhotoFileManager(msg: TLMessage, user: UserManager, file_base: String) : AbstractMediaFileManager(msg, user, file_base) { - private lateinit var photo: TLPhoto +class PhotoFileManager(json: JsonObject, user: UserManager, file_base: String) : AbstractMediaFileManager(json, user, file_base) { + //private lateinit var photo: TLPhoto override var size = 0 - private lateinit var photo_size: TLPhotoSize + //private lateinit var photo_size: TLPhotoSize override val extension = "jpg" override val letter = "p" override val name = "photo" override val description = "Photo" + + var biggestSize: JsonObject? + var biggestSizeW = 0 + var biggestSizeH = 0 init { - val p = (msg.getMedia() as TLMessageMediaPhoto).getPhoto() - if (p is TLPhoto) { - this.photo = p - - var biggest: TLPhotoSize? = null - for (s in photo.getSizes()) - if (s is TLPhotoSize) { - if (biggest == null || s.getW() > biggest.getW() && s.getH() > biggest.getH()) { - biggest = s - } - } - if (biggest == null) { - throw RuntimeException("Could not find a size for a photo.") + /*val p = (msg.getMedia() as TLMessageMediaPhoto).getPhoto()*/ + + for (elm in json["sizes"]) { + val s = elm.obj + if (biggestSize == null || (s["w"].int > biggestSizeW && s["h"].int > biggestSizeH)) { + biggestSize = s + biggestSizeW = s["w"].int + biggestSizeH = s["h"].int + size = s["size"].int // file size } - this.photo_size = biggest - this.size = biggest.getSize() - } else if (p is TLPhotoEmpty) { + if (biggestSize == null) throw RuntimeException("Could not find a size for a photo.") + } + + /*} else if (p is TLPhotoEmpty) { this.isEmpty = true } else { throwUnexpectedObjectError(p) - } + }*/ } @Throws(RpcErrorException::class, IOException::class, TimeoutException::class) override fun download(): Boolean { - if (isEmpty) return true - val loc = photo_size.getLocation() as TLFileLocation - DownloadManager.downloadFile(targetPathAndFilename, size, loc.getDcId(), loc.getVolumeId(), loc.getLocalId(), loc.getSecret()) + /*if (isEmpty) return true*/ + //val loc = photo_size.getLocation() as TLFileLocation + val loc = biggestSize["location"].obj + DownloadManager.downloadFile(targetPathAndFilename, size, loc["dcId"].int, loc["volumeId"].long, loc["localId"].int, loc["secret"].long) return true } } From bb2a291d4fb66a3077c914240d7b409352d50f84 Mon Sep 17 00:00:00 2001 From: Fabian Schlenz Date: Tue, 17 Apr 2018 06:36:39 +0200 Subject: [PATCH 5/6] MediaFileManagers now use JSON instead of the TLMessage objects. --- .../fabianonline/telegram_backup/Database.kt | 14 ++-- .../telegram_backup/DatabaseUpdates.kt | 2 +- .../telegram_backup/DownloadManager.kt | 21 ++++-- .../telegram_backup/TelegramUpdateHandler.kt | 2 +- .../de/fabianonline/telegram_backup/Utils.kt | 3 + .../AbstractMediaFileManager.kt | 19 +++--- .../mediafilemanager/DocumentFileManager.kt | 40 +++++------ .../mediafilemanager/FileManagerFactory.kt | 67 ++++++++++--------- .../mediafilemanager/GeoFileManager.kt | 18 +++-- .../mediafilemanager/PhotoFileManager.kt | 36 +++++++--- .../mediafilemanager/StickerFileManager.kt | 30 ++++----- .../UnsupportedFileManager.kt | 3 +- 12 files changed, 143 insertions(+), 112 deletions(-) diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/Database.kt b/src/main/kotlin/de/fabianonline/telegram_backup/Database.kt index 4cedd26..a9b1fdf 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/Database.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/Database.kt @@ -43,6 +43,8 @@ import java.nio.file.Files import java.nio.file.StandardCopyOption import java.nio.file.FileAlreadyExistsException import java.text.SimpleDateFormat +import com.google.gson.* +import com.github.salomonbrys.kotson.* import de.fabianonline.telegram_backup.mediafilemanager.AbstractMediaFileManager import de.fabianonline.telegram_backup.mediafilemanager.FileManagerFactory @@ -110,14 +112,16 @@ class Database constructor(val file_base: String, val user_manager: UserManager) fun getMessagesWithMediaCount() = queryInt("SELECT COUNT(*) FROM messages WHERE has_media=1") - fun getMessagesWithMedia(limit: Int = 0, offset: Int = 0): LinkedList { + fun getMessagesWithMedia(limit: Int = 0, offset: Int = 0): LinkedList> { try { - val list = LinkedList() - var query = "SELECT data FROM messages WHERE has_media=1 ORDER BY id" + val list = LinkedList>() + var query = "SELECT id, json FROM messages WHERE has_media=1 AND json IS NOT NULL ORDER BY id" if (limit > 0) query += " LIMIT ${limit} OFFSET ${offset}" val rs = executeQuery(query) + val parser = JsonParser() while (rs.next()) { - list.add(bytesToTLMessage(rs.getBytes(1))) + val obj = parser.parse(rs.getString(2)).obj + list.add(Pair(rs.getInt(1), obj)) } rs.close() return list @@ -325,7 +329,7 @@ class Database constructor(val file_base: String, val user_manager: UserManager) } ps.setString(7, text) ps.setString(8, "" + msg.getDate()) - val f = FileManagerFactory.getFileManager(msg, user_manager, file_base, settings) + val f = FileManagerFactory.getFileManager(msg, file_base, settings) if (f == null) { ps.setNull(9, Types.BOOLEAN) ps.setNull(10, Types.VARCHAR) diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt b/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt index ddf997a..ac3ac8f 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/DatabaseUpdates.kt @@ -316,7 +316,7 @@ internal class DB_Update_6(conn: Connection, db: Database) : DatabaseUpdate(conn } else { ps.setInt(1, msg.getFwdFrom().getFromId()) } - val f = FileManagerFactory.getFileManager(msg, db.user_manager, db.file_base, settings = null) + val f = FileManagerFactory.getFileManager(msg, db.file_base, settings = null) if (f == null) { ps.setNull(2, Types.VARCHAR) ps.setNull(3, Types.VARCHAR) diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/DownloadManager.kt b/src/main/kotlin/de/fabianonline/telegram_backup/DownloadManager.kt index b651bd4..779c344 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/DownloadManager.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/DownloadManager.kt @@ -36,6 +36,7 @@ import com.github.badoualy.telegram.tl.api.request.TLRequestUploadGetFile import org.slf4j.LoggerFactory import org.slf4j.Logger import com.google.gson.Gson +import com.github.salomonbrys.kotson.* import com.github.kittinunf.fuel.Fuel import com.github.kittinunf.result.Result import com.github.kittinunf.result.getAs @@ -243,20 +244,21 @@ class DownloadManager(val client: TelegramClient, val prog: DownloadProgressInte offset += limit logger.debug("Database returned {} messages with media", messages.size) prog.onMediaDownloadStart(messages.size) - for (msg in messages) { - if (msg == null) continue - val m = FileManagerFactory.getFileManager(msg, user_manager, file_base, settings=settings) + for (pair in messages) { + val id = pair.first + val json = pair.second + try { + val m = FileManagerFactory.getFileManager(json, file_base, settings=settings)!! logger.trace("message {}, {}, {}, {}, {}", - msg.getId(), - msg.getMedia().javaClass.getSimpleName().replace("TLMessageMedia", "…"), - m!!.javaClass.getSimpleName(), + id, + m.javaClass.getSimpleName(), if (m.isEmpty) "empty" else "non-empty", if (m.downloaded) "downloaded" else "not downloaded") if (m.isEmpty) { prog.onMediaDownloadedEmpty() } else if (m.downloaded) { prog.onMediaAlreadyPresent(m) - } else if (settings.max_file_age>0 && (System.currentTimeMillis() / 1000) - msg.date > settings.max_file_age * 24 * 60 * 60) { + } else if (settings.max_file_age>0 && (System.currentTimeMillis() / 1000) - json["date"].int > settings.max_file_age * 24 * 60 * 60) { prog.onMediaTooOld() } else { try { @@ -269,8 +271,13 @@ class DownloadManager(val client: TelegramClient, val prog: DownloadProgressInte } catch (e: TimeoutException) { // do nothing - skip this file prog.onMediaSkipped() + } } + } catch (e: IllegalStateException) { + println(json.toPrettyJson()) + throw e + } } } prog.onMediaDownloadFinished() diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/TelegramUpdateHandler.kt b/src/main/kotlin/de/fabianonline/telegram_backup/TelegramUpdateHandler.kt index b146612..42572a5 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/TelegramUpdateHandler.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/TelegramUpdateHandler.kt @@ -129,7 +129,7 @@ internal class TelegramUpdateHandler(val user_manager: UserManager, val db: Data db.saveMessages(vector, Kotlogram.API_LAYER, settings=settings) System.out.print('.') if (abs_msg is TLMessage && settings.download_media==true) { - val fm = FileManagerFactory.getFileManager(abs_msg, user_manager, file_base, settings) + val fm = FileManagerFactory.getFileManager(abs_msg, file_base, settings) if (fm != null && !fm.isEmpty && !fm.downloaded) { try { fm.download() diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt b/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt index 4dbb574..9a5ece5 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt @@ -224,6 +224,9 @@ fun String.anonymize(): String { fun Any.toJson(): String = Gson().toJson(this) fun Any.toPrettyJson(): String = GsonBuilder().setPrettyPrinting().create().toJson(this) +fun JsonObject.isA(name: String): Boolean = this.contains("_constructor") && this["_constructor"].string.startsWith(name + "#") +fun JsonElement.isA(name: String): Boolean = this.obj.isA(name) + class MaxTriesExceededException(): RuntimeException("Max tries exceeded") {} fun TLAbsMessage.toJson(): String { diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/AbstractMediaFileManager.kt b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/AbstractMediaFileManager.kt index bc2034e..0b36df6 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/AbstractMediaFileManager.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/AbstractMediaFileManager.kt @@ -26,14 +26,17 @@ import de.fabianonline.telegram_backup.Settings import java.io.IOException import java.io.File import java.util.concurrent.TimeoutException +import com.google.gson.* +import com.github.salomonbrys.kotson.* +import de.fabianonline.telegram_backup.* -abstract class AbstractMediaFileManager(protected var message: TLMessage, protected var user: UserManager, val file_base: String) { +abstract class AbstractMediaFileManager(private var json: JsonObject, val file_base: String) { open var isEmpty = false abstract val size: Int abstract val extension: String open val downloaded: Boolean - get() = File(targetPathAndFilename).isFile() + get() = !isEmpty && File(targetPathAndFilename).isFile() val downloading: Boolean get() = File("${targetPathAndFilename}.downloading").isFile() @@ -47,10 +50,10 @@ abstract class AbstractMediaFileManager(protected var message: TLMessage, protec open val targetFilename: String get() { - val message_id = message.getId() - var to = message.getToId() - if (to is TLPeerChannel) { - val channel_id = to.getChannelId() + val message_id = json["id"].int + var to = json["toId"].obj + if (to.isA("peerChannel")) { + val channel_id = to["channelId"].int return "channel_${channel_id}_${message_id}.$extension" } else return "${message_id}.$extension" } @@ -77,8 +80,8 @@ abstract class AbstractMediaFileManager(protected var message: TLMessage, protec } companion object { - fun throwUnexpectedObjectError(o: Any) { - throw RuntimeException("Unexpected " + o.javaClass.getName()) + fun throwUnexpectedObjectError(constructor: String) { + throw RuntimeException("Unexpected ${constructor}") } } } diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/DocumentFileManager.kt b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/DocumentFileManager.kt index fc351d4..10321ef 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/DocumentFileManager.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/DocumentFileManager.kt @@ -24,44 +24,38 @@ import com.github.badoualy.telegram.tl.exception.RpcErrorException import java.io.IOException import java.util.concurrent.TimeoutException +import com.google.gson.* +import com.github.salomonbrys.kotson.* +import de.fabianonline.telegram_backup.* -open class DocumentFileManager(msg: TLMessage, user: UserManager, file_base: String) : AbstractMediaFileManager(msg, user, file_base) { - protected var doc: TLDocument? = null +open class DocumentFileManager(message: JsonObject, file_base: String) : AbstractMediaFileManager(message, file_base) { + //protected var doc: TLDocument? = null override lateinit var extension: String open val isSticker: Boolean - get() { - if (this.isEmpty || doc == null) return false - return doc!!.getAttributes()?.filter { it is TLDocumentAttributeSticker }?.isNotEmpty() ?: false - } + get() = json.get("attributes")?.array?.any{it.obj.isA("documentAttributeSticker")} ?: false override val size: Int - get() = if (doc != null) doc!!.getSize() else 0 + get() = json["size"].int open override val letter: String = "d" open override val name: String = "document" open override val description: String = "Document" + + private val json = message["media"]["document"].obj init { - val d = (msg.getMedia() as TLMessageMediaDocument).getDocument() - if (d is TLDocument) { - this.doc = d - } else if (d is TLDocumentEmpty) { - this.isEmpty = true - } else { - throwUnexpectedObjectError(d) - } extension = processExtension() } private fun processExtension(): String { - if (doc == null) return "empty" + //if (doc == null) return "empty" var ext: String? = null var original_filename: String? = null - if (doc!!.getAttributes() != null) - for (attr in doc!!.getAttributes()) { - if (attr is TLDocumentAttributeFilename) { - original_filename = attr.getFileName() + if (json.contains("attributes")) + for (attr in json["attributes"].array) { + if (attr.obj["_constructor"].string.startsWith("documentAttributeFilename")) { + original_filename = attr.obj["fileName"].string } } if (original_filename != null) { @@ -70,7 +64,7 @@ open class DocumentFileManager(msg: TLMessage, user: UserManager, file_base: Str } if (ext == null) { - ext = extensionFromMimetype(doc!!.getMimeType()) + ext = extensionFromMimetype(json["mimeType"].string) } // Sometimes, extensions contain a trailing double quote. Remove this. Fixes #12. @@ -81,9 +75,7 @@ open class DocumentFileManager(msg: TLMessage, user: UserManager, file_base: Str @Throws(RpcErrorException::class, IOException::class, TimeoutException::class) override fun download(): Boolean { - if (doc != null) { - DownloadManager.downloadFile(targetPathAndFilename, size, doc!!.getDcId(), doc!!.getId(), doc!!.getAccessHash()) - } + DownloadManager.downloadFile(targetPathAndFilename, size, json["dcId"].int, json["id"].long, json["accessHash"].long) return true } } diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/FileManagerFactory.kt b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/FileManagerFactory.kt index af1fd1f..84693a7 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/FileManagerFactory.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/FileManagerFactory.kt @@ -36,50 +36,55 @@ import java.io.File import java.io.FileOutputStream import java.util.ArrayList import java.util.LinkedList +import java.util.NoSuchElementException import java.net.URL import java.util.concurrent.TimeoutException import com.google.gson.* import com.github.salomonbrys.kotson.* +import de.fabianonline.telegram_backup.* import org.apache.commons.io.FileUtils object FileManagerFactory { - fun getFileManager(m: TLMessage?, u: UserManager, file_base: String, settings: Settings?): AbstractMediaFileManager? { + fun getFileManager(m: TLMessage?, file_base: String, settings: Settings?): AbstractMediaFileManager? { if (m == null) return null val json = Gson().toJsonTree(m).obj - return getFileManager(json, u, file_base, settings) + return getFileManager(json, file_base, settings) } - fun getFileManager(m: JsonObject?, u: UserManager, file_base: String, settings: Settings?): AbstractMediaFileManager? { - if (m == null) return null - val media = m.get("media")?.obj ?: return null - - if (media.contains("photo")) { - return PhotoFileManager(media["photo"].obj, u, file_base) + fun getFileManager(message: JsonObject?, file_base: String, settings: Settings?): AbstractMediaFileManager? { + if (message == null) return null + try { + val media = message.get("media")?.obj ?: return null + + if (media.isA("messageMediaPhoto")) { + return PhotoFileManager(message, file_base) + } else if (media.isA("messageMediaDocument")) { + val d = DocumentFileManager(message, file_base) + return if (d.isSticker) StickerFileManager(message, file_base) else d + } else if (media.isA("messageMediaGeo")) { + return GeoFileManager(message, file_base, settings) + } else if (media.isA("messageMediaEmpty")) { + return UnsupportedFileManager(message, file_base, "empty") + } else if (media.isA("messageMediaUnsupported")) { + return UnsupportedFileManager(message, file_base, "unsupported") + } else if (media.isA("messageMediaWebPage")) { + return UnsupportedFileManager(message, file_base, "webpage") + } else if (media.isA("messageMediaContact")) { + return UnsupportedFileManager(message, file_base, "contact") + } else if (media.isA("messageMediaVenue")) { + return UnsupportedFileManager(message, file_base, "venue") + } else { + AbstractMediaFileManager.throwUnexpectedObjectError(media["_constructor"].string) + } + } catch (e: IllegalStateException) { + println(message.toPrettyJson()) + throw e + } catch (e: NoSuchElementException) { + println(message.toPrettyJson()) + throw e } - - /*if (media is TLMessageMediaPhoto) { - return PhotoFileManager(m, u, file_base) - } else if (media is TLMessageMediaDocument) { - val d = DocumentFileManager(m, u, file_base) - return if (d.isSticker) { - StickerFileManager(m, u, file_base) - } else d - } else if (media is TLMessageMediaGeo) { - return GeoFileManager(m, u, file_base, settings) - } else if (media is TLMessageMediaEmpty) { - return UnsupportedFileManager(m, u, file_base, "empty") - } else if (media is TLMessageMediaUnsupported) { - return UnsupportedFileManager(m, u, file_base, "unsupported") - } else if (media is TLMessageMediaWebPage) { - return UnsupportedFileManager(m, u, file_base, "webpage") - } else if (media is TLMessageMediaContact) { - return UnsupportedFileManager(m, u, file_base, "contact") - } else if (media is TLMessageMediaVenue) { - return UnsupportedFileManager(m, u, file_base, "venue") - } else { - AbstractMediaFileManager.throwUnexpectedObjectError(media) - }*/ + return null } } diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/GeoFileManager.kt b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/GeoFileManager.kt index a47041c..b933533 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/GeoFileManager.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/GeoFileManager.kt @@ -25,9 +25,12 @@ import de.fabianonline.telegram_backup.Settings import java.io.IOException import java.io.File +import com.google.gson.* +import com.github.salomonbrys.kotson.* +import de.fabianonline.telegram_backup.Utils -class GeoFileManager(msg: TLMessage, user: UserManager, file_base: String, val settings: Settings?) : AbstractMediaFileManager(msg, user, file_base) { - protected lateinit var geo: TLGeoPoint +class GeoFileManager(message: JsonObject, file_base: String, val settings: Settings?) : AbstractMediaFileManager(message, file_base) { + //protected lateinit var geo: TLGeoPoint // We don't know the size, so we just guess. override val size: Int @@ -42,8 +45,11 @@ class GeoFileManager(msg: TLMessage, user: UserManager, file_base: String, val s override val letter = "g" override val name = "geo" override val description = "Geolocation" + + val json = message["media"]["geo"].obj init { + /* val g = (msg.getMedia() as TLMessageMediaGeo).getGeo() if (g is TLGeoPoint) { this.geo = g @@ -51,16 +57,16 @@ class GeoFileManager(msg: TLMessage, user: UserManager, file_base: String, val s this.isEmpty = true } else { throwUnexpectedObjectError(g) - } + }*/ } @Throws(IOException::class) override fun download(): Boolean { val url = "https://maps.googleapis.com/maps/api/staticmap?" + - "center=${geo.getLat()},${geo.getLong()}&" + - "markers=color:red|${geo.getLat()},${geo.getLong()}&" + + "center=${json["lat"].float},${json["_long"].float}&" + + "markers=color:red|${json["lat"].float},${json["_long"].float}&" + "zoom=14&size=300x150&scale=2&format=png&" + - "key=" + (settings?.gmaps_key ?: Config.SECRET_GMAPS) + "key=" + (settings?.gmaps_key) return DownloadManager.downloadExternalFile(targetPathAndFilename, url) } } diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/PhotoFileManager.kt b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/PhotoFileManager.kt index 068c6d2..024b1c8 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/PhotoFileManager.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/PhotoFileManager.kt @@ -25,7 +25,11 @@ import com.github.badoualy.telegram.tl.exception.RpcErrorException import java.io.IOException import java.util.concurrent.TimeoutException -class PhotoFileManager(json: JsonObject, user: UserManager, file_base: String) : AbstractMediaFileManager(json, user, file_base) { +import com.google.gson.* +import com.github.salomonbrys.kotson.* +import de.fabianonline.telegram_backup.* + +class PhotoFileManager(message: JsonObject, file_base: String) : AbstractMediaFileManager(message, file_base) { //private lateinit var photo: TLPhoto override var size = 0 //private lateinit var photo_size: TLPhotoSize @@ -35,22 +39,33 @@ class PhotoFileManager(json: JsonObject, user: UserManager, file_base: String) : override val name = "photo" override val description = "Photo" - var biggestSize: JsonObject? + val biggestSize: JsonObject var biggestSizeW = 0 var biggestSizeH = 0 + + val json = message["media"]["photo"].obj + override var isEmpty = json.isA("photoEmpty") init { /*val p = (msg.getMedia() as TLMessageMediaPhoto).getPhoto()*/ + if (!isEmpty) { + var bsTemp: JsonObject? = null - for (elm in json["sizes"]) { - val s = elm.obj - if (biggestSize == null || (s["w"].int > biggestSizeW && s["h"].int > biggestSizeH)) { - biggestSize = s - biggestSizeW = s["w"].int - biggestSizeH = s["h"].int - size = s["size"].int // file size + for (elm in json["sizes"].array) { + val s = elm.obj + if (!s.isA("photoSize")) continue + if (bsTemp == null || (s["w"].int > biggestSizeW && s["h"].int > biggestSizeH)) { + bsTemp = s + biggestSizeW = s["w"].int + biggestSizeH = s["h"].int + size = s["size"].int // file size + } } - if (biggestSize == null) throw RuntimeException("Could not find a size for a photo.") + + if (bsTemp == null) throw RuntimeException("Could not find a size for a photo.") + biggestSize = bsTemp + } else { + biggestSize = JsonObject() } /*} else if (p is TLPhotoEmpty) { @@ -64,6 +79,7 @@ class PhotoFileManager(json: JsonObject, user: UserManager, file_base: String) : override fun download(): Boolean { /*if (isEmpty) return true*/ //val loc = photo_size.getLocation() as TLFileLocation + val loc = biggestSize["location"].obj DownloadManager.downloadFile(targetPathAndFilename, size, loc["dcId"].int, loc["volumeId"].long, loc["localId"].int, loc["secret"].long) return true diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/StickerFileManager.kt b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/StickerFileManager.kt index 6985d39..1056b07 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/StickerFileManager.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/StickerFileManager.kt @@ -49,29 +49,23 @@ import java.util.concurrent.TimeoutException import org.apache.commons.io.FileUtils -class StickerFileManager(msg: TLMessage, user: UserManager, file_base: String) : DocumentFileManager(msg, user, file_base) { +import com.google.gson.* +import com.github.salomonbrys.kotson.* +import de.fabianonline.telegram_backup.* + +class StickerFileManager(message: JsonObject, file_base: String) : DocumentFileManager(message, file_base) { override val isSticker = true + + val json = message["media"]["document"].obj + val sticker = json["attributes"].array.first{it.obj.isA("documentAttributeSticker")}.obj + override var isEmpty = sticker["stickerset"].obj.isA("inputStickerSetEmpty") private val filenameBase: String get() { - var sticker: TLDocumentAttributeSticker? = null - for (attr in doc!!.getAttributes()) { - if (attr is TLDocumentAttributeSticker) { - sticker = attr - } - } - - val file = StringBuilder() - val set = sticker!!.getStickerset() - if (set is TLInputStickerSetShortName) { - file.append(set.getShortName()) - } else if (set is TLInputStickerSetID) { - file.append(set.getId()) - } - file.append("_") - file.append(sticker.getAlt().hashCode()) - return file.toString() + val set = sticker["stickerset"].obj.get("shortName").nullString ?: sticker["stickerset"].obj.get("id").string + val hash = sticker["alt"].string.hashCode() + return "${set}_${hash}" } override val targetFilename: String diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/UnsupportedFileManager.kt b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/UnsupportedFileManager.kt index 66ac8d2..7e7a7e4 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/UnsupportedFileManager.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/mediafilemanager/UnsupportedFileManager.kt @@ -19,8 +19,9 @@ package de.fabianonline.telegram_backup.mediafilemanager import de.fabianonline.telegram_backup.UserManager import com.github.badoualy.telegram.tl.api.* +import com.google.gson.JsonObject -class UnsupportedFileManager(msg: TLMessage, user: UserManager, type: String, file_base: String) : AbstractMediaFileManager(msg, user, file_base) { +class UnsupportedFileManager(json: JsonObject, file_base: String, type: String) : AbstractMediaFileManager(json, file_base) { override var name = type override val targetFilename = "" override val targetPath = "" From 11a6318a269baa4747767ae686d3db370b982179 Mon Sep 17 00:00:00 2001 From: Fabian Schlenz Date: Thu, 19 Apr 2018 17:48:11 +0200 Subject: [PATCH 6/6] JSON objects now also contain a property api_layer containing their (surprise!) api_layer. --- .../de/fabianonline/telegram_backup/Utils.kt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt b/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt index 9a5ece5..878d07d 100644 --- a/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt +++ b/src/main/kotlin/de/fabianonline/telegram_backup/Utils.kt @@ -18,6 +18,9 @@ package de.fabianonline.telegram_backup import com.github.badoualy.telegram.tl.exception.RpcErrorException import com.github.badoualy.telegram.tl.api.TLAbsMessage +import com.github.badoualy.telegram.tl.api.TLAbsUser +import com.github.badoualy.telegram.tl.api.TLAbsChat +import com.github.badoualy.telegram.api.Kotlogram import java.io.File import java.util.Vector import java.util.concurrent.TimeUnit @@ -230,8 +233,21 @@ fun JsonElement.isA(name: String): Boolean = this.obj.isA(name) class MaxTriesExceededException(): RuntimeException("Max tries exceeded") {} fun TLAbsMessage.toJson(): String { - val json = Gson().toJsonTree(this) + val json = Gson().toJsonTree(this).obj cleanUpMessageJson(json) + json["api_layer"] = Kotlogram.API_LAYER + return json.toString() +} + +fun TLAbsChat.toJson(): String { + val json = Gson().toJsonTree(this).obj + json["api_layer"] = Kotlogram.API_LAYER + return json.toString() +} + +fun TLAbsUser.toJson(): String { + val json = Gson().toJsonTree(this).obj + json["api_layer"] = Kotlogram.API_LAYER return json.toString() }