mirror of
				https://github.com/fabianonline/telegram_backup.git
				synced 2025-11-04 01:27:47 +00:00 
			
		
		
		
	Merge branch 'feature-json2'
This commit is contained in:
		@@ -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'
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -42,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
 | 
			
		||||
@@ -109,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<TLMessage?> {
 | 
			
		||||
	fun getMessagesWithMedia(limit: Int = 0, offset: Int = 0): LinkedList<Pair<Int, JsonObject>> {
 | 
			
		||||
		try {
 | 
			
		||||
			val list = LinkedList<TLMessage?>()
 | 
			
		||||
			var query = "SELECT data FROM messages WHERE has_media=1 ORDER BY id"
 | 
			
		||||
			val list = LinkedList<Pair<Int, JsonObject>>()
 | 
			
		||||
			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<Int, JsonObject>(rs.getInt(1), obj))
 | 
			
		||||
			}
 | 
			
		||||
			rs.close()
 | 
			
		||||
			return list
 | 
			
		||||
@@ -266,13 +271,10 @@ class Database constructor(val file_base: String, val user_manager: UserManager)
 | 
			
		||||
 | 
			
		||||
	@Synchronized
 | 
			
		||||
	fun saveMessages(all: TLVector<TLAbsMessage>, 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)
 | 
			
		||||
 | 
			
		||||
@@ -327,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)
 | 
			
		||||
@@ -343,6 +345,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 +384,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 +401,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 +423,23 @@ class Database constructor(val file_base: String, val user_manager: UserManager)
 | 
			
		||||
	fun saveChats(all: TLVector<TLAbsChat>) {
 | 
			
		||||
		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 +480,14 @@ class Database constructor(val file_base: String, val user_manager: UserManager)
 | 
			
		||||
	fun saveUsers(all: TLVector<TLAbsUser>) {
 | 
			
		||||
		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 +497,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 +507,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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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() {
 | 
			
		||||
@@ -313,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)
 | 
			
		||||
@@ -451,3 +454,46 @@ 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")
 | 
			
		||||
		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: 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, 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))
 | 
			
		||||
				val json = if (msg==null) Gson().toJson(null) else 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)
 | 
			
		||||
			offset += limit
 | 
			
		||||
			print(".")
 | 
			
		||||
		} while (i >= limit)
 | 
			
		||||
		println()
 | 
			
		||||
		ps.close()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -242,20 +243,21 @@ class DownloadManager(val client: TelegramClient, val prog: DownloadProgressInte
 | 
			
		||||
			if (messages.size == 0) break
 | 
			
		||||
			offset += limit
 | 
			
		||||
			logger.debug("Database returned {} messages with media", 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.onMediaSkipped()
 | 
			
		||||
				} else if (settings.max_file_size>0 && settings.max_file_size*1024*1024 > m.size) {
 | 
			
		||||
					prog.onMediaSkipped()
 | 
			
		||||
@@ -272,6 +274,10 @@ class DownloadManager(val client: TelegramClient, val prog: DownloadProgressInte
 | 
			
		||||
						prog.onMediaFailed()
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				} catch (e: IllegalStateException) {
 | 
			
		||||
					println(json.toPrettyJson())
 | 
			
		||||
					throw e
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		prog.onMediaDownloadFinished()
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
 
 | 
			
		||||
@@ -17,11 +17,16 @@
 | 
			
		||||
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
 | 
			
		||||
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
 | 
			
		||||
@@ -222,4 +227,42 @@ 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 {
 | 
			
		||||
	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()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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}")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -36,38 +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 media = m.getMedia() ?: return null
 | 
			
		||||
 | 
			
		||||
		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)
 | 
			
		||||
		val json = Gson().toJsonTree(m).obj
 | 
			
		||||
		return getFileManager(json, file_base, settings)
 | 
			
		||||
	}
 | 
			
		||||
	            
 | 
			
		||||
	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
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return null
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -43,7 +46,10 @@ class GeoFileManager(msg: TLMessage, user: UserManager, file_base: String, val s
 | 
			
		||||
	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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,45 +25,63 @@ 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
 | 
			
		||||
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
 | 
			
		||||
	//private lateinit var photo_size: TLPhotoSize
 | 
			
		||||
 | 
			
		||||
	override val extension = "jpg"
 | 
			
		||||
	override val letter = "p"
 | 
			
		||||
	override val name = "photo"
 | 
			
		||||
	override val description = "Photo"
 | 
			
		||||
	
 | 
			
		||||
	init {
 | 
			
		||||
		val p = (msg.getMedia() as TLMessageMediaPhoto).getPhoto()
 | 
			
		||||
		if (p is TLPhoto) {
 | 
			
		||||
			this.photo = p
 | 
			
		||||
	val biggestSize: JsonObject
 | 
			
		||||
	var biggestSizeW = 0
 | 
			
		||||
	var biggestSizeH = 0
 | 
			
		||||
	
 | 
			
		||||
			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
 | 
			
		||||
	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"].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 (biggest == 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()
 | 
			
		||||
		}
 | 
			
		||||
			this.photo_size = biggest
 | 
			
		||||
			this.size = biggest.getSize()
 | 
			
		||||
		} else if (p is TLPhotoEmpty) {
 | 
			
		||||
			
 | 
			
		||||
		/*} 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
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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 = ""
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user