1
0
mirror of https://github.com/fabianonline/telegram_backup.git synced 2024-11-23 01:06:17 +00:00

Kotlin-Code is now compilable. Now let's go on to fix all those warning...

This commit is contained in:
Fabian Schlenz 2017-12-11 12:14:25 +01:00
parent 9832d429b0
commit f75a90936d
22 changed files with 319 additions and 393 deletions

View File

@ -27,7 +27,7 @@ import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.IOException import java.io.IOException
internal class ApiStorage(prefix: String) : TelegramApiStorage { internal class ApiStorage(prefix: String?) : TelegramApiStorage {
private var prefix: String? = null private var prefix: String? = null
private var do_save = false private var do_save = false
private var auth_key: AuthKey? = null private var auth_key: AuthKey? = null
@ -39,7 +39,7 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
this.setPrefix(prefix) this.setPrefix(prefix)
} }
fun setPrefix(prefix: String) { fun setPrefix(prefix: String?) {
this.prefix = prefix this.prefix = prefix
this.do_save = this.prefix != null this.do_save = this.prefix != null
if (this.do_save) { if (this.do_save) {
@ -57,7 +57,7 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
} }
} }
fun saveAuthKey(authKey: AuthKey) { override fun saveAuthKey(authKey: AuthKey) {
this.auth_key = authKey this.auth_key = authKey
this._saveAuthKey() this._saveAuthKey()
} }
@ -65,7 +65,7 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
private fun _saveAuthKey() { private fun _saveAuthKey() {
if (this.do_save && this.auth_key != null) { if (this.do_save && this.auth_key != null) {
try { try {
FileUtils.writeByteArrayToFile(this.file_auth_key, this.auth_key!!.getKey()) FileUtils.writeByteArrayToFile(this.file_auth_key, this.auth_key!!.key)
} catch (e: IOException) { } catch (e: IOException) {
e.printStackTrace() e.printStackTrace()
} }
@ -73,7 +73,7 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
} }
} }
fun loadAuthKey(): AuthKey? { override fun loadAuthKey(): AuthKey? {
if (this.auth_key != null) return this.auth_key if (this.auth_key != null) return this.auth_key
if (this.file_auth_key != null) { if (this.file_auth_key != null) {
try { try {
@ -87,7 +87,7 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
return null return null
} }
fun saveDc(dc: DataCenter) { override fun saveDc(dc: DataCenter) {
this.dc = dc this.dc = dc
this._saveDc() this._saveDc()
} }
@ -103,7 +103,7 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
} }
} }
fun loadDc(): DataCenter? { override fun loadDc(): DataCenter? {
if (this.dc != null) return this.dc if (this.dc != null) return this.dc
if (this.file_dc != null) { if (this.file_dc != null) {
try { try {
@ -117,7 +117,7 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
return null return null
} }
fun deleteAuthKey() { override fun deleteAuthKey() {
if (this.do_save) { if (this.do_save) {
try { try {
FileUtils.forceDelete(this.file_auth_key) FileUtils.forceDelete(this.file_auth_key)
@ -128,7 +128,7 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
} }
} }
fun deleteDc() { override fun deleteDc() {
if (this.do_save) { if (this.do_save) {
try { try {
FileUtils.forceDelete(this.file_dc) FileUtils.forceDelete(this.file_dc)
@ -139,9 +139,9 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
} }
} }
fun saveSession(session: MTSession) {} override fun saveSession(session: MTSession?) {}
fun loadSession(): MTSession? { override fun loadSession(): MTSession? {
return null return null
} }
} }

View File

@ -30,29 +30,24 @@ import org.slf4j.Logger
class CommandLineController { class CommandLineController {
private val storage:ApiStorage private val storage:ApiStorage
var app:TelegramApp var app:TelegramApp
private val line:String
get() { private fun getLine():String {
if (System.console() != null) if (System.console() != null) {
{
return System.console().readLine("> ") return System.console().readLine("> ")
} } else {
else
{
print("> ") print("> ")
return Scanner(System.`in`).nextLine() return Scanner(System.`in`).nextLine()
} }
} }
private val password:String
get() { private fun getPassword():String {
if (System.console() != null) if (System.console() != null) {
{
return String(System.console().readPassword("> ")) return String(System.console().readPassword("> "))
} } else {
else return getLine()
{
return line
} }
} }
init{ init{
logger.info("CommandLineController started. App version {}", Config.APP_APPVER) logger.info("CommandLineController started. App version {}", Config.APP_APPVER)
this.printHeader() this.printHeader()
@ -67,7 +62,7 @@ class CommandLineController {
} }
else if (CommandLineOptions.cmd_license) else if (CommandLineOptions.cmd_license)
{ {
this.show_license() CommandLineController.show_license()
System.exit(0) System.exit(0)
} }
this.setupFileBase() this.setupFileBase()
@ -92,16 +87,16 @@ class CommandLineController {
logger.info("Initializing UserManager") logger.info("Initializing UserManager")
UserManager.init(client) UserManager.init(client)
val user = UserManager.getInstance() val user = UserManager.getInstance()
if (!CommandLineOptions.cmd_login && !user.isLoggedIn()) if (!CommandLineOptions.cmd_login && !user.loggedIn)
{ {
println("Your authorization data is invalid or missing. You will have to login with Telegram again.") println("Your authorization data is invalid or missing. You will have to login with Telegram again.")
CommandLineOptions.cmd_login = true CommandLineOptions.cmd_login = true
} }
if (account != null && user.isLoggedIn()) if (account != null && user.loggedIn)
{ {
if (account != "+" + user.getUser().getPhone()) if (account != "+" + user.user!!.getPhone())
{ {
logger.error("Account: {}, user.getUser().getPhone(): +{}", Utils.anonymize(account), Utils.anonymize(user.getUser().getPhone())) logger.error("Account: {}, user.user!!.getPhone(): +{}", Utils.anonymize(account), Utils.anonymize(user.user!!.getPhone()))
throw RuntimeException("Account / User mismatch") throw RuntimeException("Account / User mismatch")
} }
} }
@ -137,7 +132,7 @@ class CommandLineController {
logger.debug("CommandLineOptions.val_export: {}", CommandLineOptions.val_export) logger.debug("CommandLineOptions.val_export: {}", CommandLineOptions.val_export)
if (CommandLineOptions.val_export != null) if (CommandLineOptions.val_export != null)
{ {
if (CommandLineOptions.val_export.toLowerCase().equals("html")) if (CommandLineOptions.val_export!!.toLowerCase().equals("html"))
{ {
(HTMLExporter()).export() (HTMLExporter()).export()
System.exit(0) System.exit(0)
@ -147,9 +142,9 @@ class CommandLineController {
show_error("Unknown export format.") show_error("Unknown export format.")
} }
} }
if (user.isLoggedIn()) if (user.loggedIn)
{ {
System.out.println("You are logged in as " + Utils.anonymize(user.getUserString())) System.out.println("You are logged in as " + Utils.anonymize(user.userString))
} }
else else
{ {
@ -202,13 +197,13 @@ class CommandLineController {
logger.debug("Target dir at startup: {}", Utils.anonymize(Config.FILE_BASE)) logger.debug("Target dir at startup: {}", Utils.anonymize(Config.FILE_BASE))
if (CommandLineOptions.val_target != null) if (CommandLineOptions.val_target != null)
{ {
Config.FILE_BASE = CommandLineOptions.val_target Config.FILE_BASE = CommandLineOptions.val_target!!
} }
logger.debug("Target dir after options: {}", Utils.anonymize(Config.FILE_BASE)) logger.debug("Target dir after options: {}", Utils.anonymize(Config.FILE_BASE))
System.out.println("Base directory for files: " + Utils.anonymize(Config.FILE_BASE)) System.out.println("Base directory for files: " + Utils.anonymize(Config.FILE_BASE))
} }
private fun selectAccount():String { private fun selectAccount():String? {
val account:String = null var account = "none"
val accounts = Utils.getAccounts() val accounts = Utils.getAccounts()
if (CommandLineOptions.cmd_login) if (CommandLineOptions.cmd_login)
{ {
@ -217,9 +212,9 @@ class CommandLineController {
} }
else if (CommandLineOptions.val_account != null) else if (CommandLineOptions.val_account != null)
{ {
logger.debug("Account requested: {}", Utils.anonymize(CommandLineOptions.val_account)) logger.debug("Account requested: {}", Utils.anonymize(CommandLineOptions.val_account!!))
logger.trace("Checking accounts for match.") logger.trace("Checking accounts for match.")
val found = false var found = false
for (acc in accounts) for (acc in accounts)
{ {
logger.trace("Checking {}", Utils.anonymize(acc)) logger.trace("Checking {}", Utils.anonymize(acc))
@ -232,16 +227,17 @@ class CommandLineController {
} }
if (!found) if (!found)
{ {
show_error("Couldn't find account '" + Utils.anonymize(CommandLineOptions.val_account) + "'. Maybe you want to use '--login' first?") show_error("Couldn't find account '" + Utils.anonymize(CommandLineOptions.val_account!!) + "'. Maybe you want to use '--login' first?")
} }
account = CommandLineOptions.val_account account = CommandLineOptions.val_account!!
} }
else if (accounts.size() == 0) else if (accounts.size == 0)
{ {
println("No accounts found. Starting login process...") println("No accounts found. Starting login process...")
CommandLineOptions.cmd_login = true CommandLineOptions.cmd_login = true
return null
} }
else if (accounts.size() == 1) else if (accounts.size == 1)
{ {
account = accounts.firstElement() account = accounts.firstElement()
System.out.println("Using only available account: " + Utils.anonymize(account)) System.out.println("Using only available account: " + Utils.anonymize(account))
@ -251,8 +247,9 @@ class CommandLineController {
show_error(("You didn't specify which account to use.\n" + show_error(("You didn't specify which account to use.\n" +
"Use '--account <x>' to use account <x>.\n" + "Use '--account <x>' to use account <x>.\n" +
"Use '--list-accounts' to see all available accounts.")) "Use '--list-accounts' to see all available accounts."))
System.exit(1)
} }
logger.debug("accounts.size(): {}", accounts.size()) logger.debug("accounts.size: {}", accounts.size)
logger.debug("account: {}", Utils.anonymize(account)) logger.debug("account: {}", Utils.anonymize(account))
return account return account
} }
@ -260,45 +257,48 @@ class CommandLineController {
println() println()
println("Stats:") println("Stats:")
val format = "%40s: %d%n" val format = "%40s: %d%n"
System.out.format(format, "Number of accounts", Utils.getAccounts().size()) System.out.format(format, "Number of accounts", Utils.getAccounts().size)
System.out.format(format, "Number of messages", Database.getInstance().getMessageCount()) System.out.format(format, "Number of messages", Database.getInstance().getMessageCount())
System.out.format(format, "Number of chats", Database.getInstance().getChatCount()) System.out.format(format, "Number of chats", Database.getInstance().getChatCount())
System.out.format(format, "Number of users", Database.getInstance().getUserCount()) System.out.format(format, "Number of users", Database.getInstance().getUserCount())
System.out.format(format, "Top message ID", Database.getInstance().getTopMessageID()) System.out.format(format, "Top message ID", Database.getInstance().getTopMessageID())
println() println()
println("Media Types:") println("Media Types:")
for (pair in Database.getInstance().getMessageMediaTypesWithCount().entrySet()) for ((key, value) in Database.getInstance().getMessageMediaTypesWithCount())
{ {
System.out.format(format, pair.key, pair.value) System.out.format(format, key, value)
} }
println() println()
println("Api layers of messages:") println("Api layers of messages:")
for (pair in Database.getInstance().getMessageApiLayerWithCount().entrySet()) for ((key, value) in Database.getInstance().getMessageApiLayerWithCount())
{ {
System.out.format(format, pair.key, pair.value) System.out.format(format, key, value)
} }
} }
@Throws(RpcErrorException::class, IOException::class) @Throws(RpcErrorException::class, IOException::class)
private fun cmd_login(phone:String) { private fun cmd_login(phoneToUse:String?) {
val user = UserManager.getInstance() val user = UserManager.getInstance()
if (phone == null) val phone: String
if (phoneToUse == null)
{ {
println("Please enter your phone number in international format.") println("Please enter your phone number in international format.")
println("Example: +4917077651234") println("Example: +4917077651234")
phone = line phone = getLine()
} else {
phone = phoneToUse
} }
user.sendCodeToPhoneNumber(phone) user.sendCodeToPhoneNumber(phone)
println("Telegram sent you a code. Please enter it here.") println("Telegram sent you a code. Please enter it here.")
val code = line val code = getLine()
user.verifyCode(code) user.verifyCode(code)
if (user.isPasswordNeeded()) if (user.isPasswordNeeded)
{ {
println("We also need your account password. Please enter it now. It should not be printed, so it's okay if you see nothing while typing it.") println("We also need your account password. Please enter it now. It should not be printed, so it's okay if you see nothing while typing it.")
val pw = password val pw = getPassword()
user.verifyPassword(pw) user.verifyPassword(pw)
} }
storage.setPrefix("+" + user.getUser().getPhone()) storage.setPrefix("+" + user.user!!.getPhone())
System.out.println("Everything seems fine. Please run this tool again with '--account +" + Utils.anonymize(user.getUser().getPhone()) + " to use this account.") System.out.println("Everything seems fine. Please run this tool again with '--account +" + Utils.anonymize(user.user!!.getPhone()) + " to use this account.")
} }
private fun show_help() { private fun show_help() {
println("Valid options are:") println("Valid options are:")
@ -340,14 +340,14 @@ class CommandLineController {
} }
companion object { companion object {
private val logger = LoggerFactory.getLogger(CommandLineController::class.java) private val logger = LoggerFactory.getLogger(CommandLineController::class.java)
fun show_error(error:String) {
public fun show_error(error:String) {
logger.error(error) logger.error(error)
println("ERROR: " + error) println("ERROR: " + error)
System.exit(1) System.exit(1)
} }
fun show_license() { fun show_license() {
println("TODO: Print the GPL.") println("TODO: Print the GPL.")
}
} }
} }
}

View File

@ -23,7 +23,7 @@ internal class CommandLineDownloadProgress : DownloadProgressInterface {
private var mediaCount = 0 private var mediaCount = 0
private var i = 0 private var i = 0
fun onMessageDownloadStart(count: Int, source: String?) { override fun onMessageDownloadStart(count: Int, source: String?) {
i = 0 i = 0
if (source == null) { if (source == null) {
System.out.println("Downloading $count messages.") System.out.println("Downloading $count messages.")
@ -32,56 +32,56 @@ internal class CommandLineDownloadProgress : DownloadProgressInterface {
} }
} }
fun onMessageDownloaded(number: Int) { override fun onMessageDownloaded(number: Int) {
i += number i += number
System.out.print("..." + i) print("..." + i)
} }
fun onMessageDownloadFinished() { override fun onMessageDownloadFinished() {
System.out.println(" done.") println(" done.")
} }
fun onMediaDownloadStart(count: Int) { override fun onMediaDownloadStart(count: Int) {
i = 0 i = 0
mediaCount = count mediaCount = count
System.out.println("Checking and downloading media.") println("Checking and downloading media.")
System.out.println("Legend:") println("Legend:")
System.out.println("'V' - Video 'P' - Photo 'D' - Document") println("'V' - Video 'P' - Photo 'D' - Document")
System.out.println("'S' - Sticker 'A' - Audio 'G' - Geolocation") println("'S' - Sticker 'A' - Audio 'G' - Geolocation")
System.out.println("'.' - Previously downloaded file 'e' - Empty file") println("'.' - Previously downloaded file 'e' - Empty file")
System.out.println("' ' - Ignored media type (weblinks or contacts, for example)") println("' ' - Ignored media type (weblinks or contacts, for example)")
System.out.println("'x' - File skipped because of timeout errors") println("'x' - File skipped because of timeout errors")
System.out.println("" + count + " Files to check / download") println("" + count + " Files to check / download")
} }
fun onMediaDownloaded(fm: AbstractMediaFileManager) { override fun onMediaDownloaded(fm: AbstractMediaFileManager) {
show(fm.getLetter().toUpperCase()) show(fm.letter.toUpperCase())
} }
fun onMediaDownloadedEmpty() { override fun onMediaDownloadedEmpty() {
show("e") show("e")
} }
fun onMediaAlreadyPresent(fm: AbstractMediaFileManager) { override fun onMediaAlreadyPresent(fm: AbstractMediaFileManager) {
show(".") show(".")
} }
fun onMediaSkipped() { override fun onMediaSkipped() {
show("x") show("x")
} }
fun onMediaDownloadFinished() { override fun onMediaDownloadFinished() {
showNewLine() showNewLine()
System.out.println("Done.") println("Done.")
} }
private fun show(letter: String) { private fun show(letter: String) {
System.out.print(letter) print(letter)
i++ i++
if (i % 100 == 0) showNewLine() if (i % 100 == 0) showNewLine()
} }
private fun showNewLine() { private fun showNewLine() {
System.out.println(" - $i/$mediaCount") println(" - $i/$mediaCount")
} }
} }

View File

@ -92,7 +92,7 @@ internal object CommandLineOptions {
} }
if (last_cmd != null) if (last_cmd != null)
{ {
CommandLineController.show_error("Command " + last_cmd + " had no parameter set.") CommandLineController.show_error("Command $last_cmd had no parameter set.")
} }
} }
} }

View File

@ -37,12 +37,12 @@ object Config {
val FILE_FILES_BASE = "files" val FILE_FILES_BASE = "files"
val FILE_STICKER_BASE = "stickers" val FILE_STICKER_BASE = "stickers"
var DELAY_AFTER_GET_MESSAGES = 400 var DELAY_AFTER_GET_MESSAGES: Long = 400
var DELAY_AFTER_GET_FILE = 100 var DELAY_AFTER_GET_FILE: Long = 100
var GET_MESSAGES_BATCH_SIZE = 200 var GET_MESSAGES_BATCH_SIZE = 200
var RENAMING_MAX_TRIES = 5 var RENAMING_MAX_TRIES = 5
var RENAMING_DELAY = 1000 var RENAMING_DELAY: Long = 1000
val SECRET_GMAPS = "AIzaSyBEtUDhCQKEH6i2Mn1GAiQ9M_tLN0vxHIs" val SECRET_GMAPS = "AIzaSyBEtUDhCQKEH6i2Mn1GAiQ9M_tLN0vxHIs"

View File

@ -52,8 +52,7 @@ class Database private constructor(var client: TelegramClient) {
private var stmt: Statement? = null private var stmt: Statement? = null
var user_manager: UserManager var user_manager: UserManager
val topMessageID: Int fun getTopMessageID(): Int {
get() {
try { try {
val rs = stmt!!.executeQuery("SELECT MAX(message_id) FROM messages WHERE source_type IN ('group', 'dialog')") val rs = stmt!!.executeQuery("SELECT MAX(message_id) FROM messages WHERE source_type IN ('group', 'dialog')")
rs.next() rs.next()
@ -64,18 +63,15 @@ class Database private constructor(var client: TelegramClient) {
} }
val messageCount: Int fun getMessageCount(): Int = queryInt("SELECT COUNT(*) FROM messages")
get() = queryInt("SELECT COUNT(*) FROM messages") fun getChatCount(): Int = queryInt("SELECT COUNT(*) FROM chats")
val chatCount: Int fun getUserCount(): Int = queryInt("SELECT COUNT(*) FROM users")
get() = queryInt("SELECT COUNT(*) FROM chats")
val userCount: Int
get() = queryInt("SELECT COUNT(*) FROM users")
val missingIDs: LinkedList<Integer> val missingIDs: LinkedList<Int>
get() { get() {
try { try {
val missing = LinkedList<Integer>() val missing = LinkedList<Int>()
val max = topMessageID val max = getTopMessageID()
val rs = stmt!!.executeQuery("SELECT message_id FROM messages WHERE source_type IN ('group', 'dialog') ORDER BY id") val rs = stmt!!.executeQuery("SELECT message_id FROM messages WHERE source_type IN ('group', 'dialog') ORDER BY id")
rs.next() rs.next()
var id = rs.getInt(1) var id = rs.getInt(1)
@ -99,10 +95,9 @@ class Database private constructor(var client: TelegramClient) {
} }
val messagesWithMedia: LinkedList<TLMessage> fun getMessagesWithMedia(): LinkedList<TLMessage?> {
get() {
try { try {
val list = LinkedList<TLMessage>() val list = LinkedList<TLMessage?>()
val rs = stmt!!.executeQuery("SELECT data FROM messages WHERE has_media=1") val rs = stmt!!.executeQuery("SELECT data FROM messages WHERE has_media=1")
while (rs.next()) { while (rs.next()) {
list.add(bytesToTLMessage(rs.getBytes(1))) list.add(bytesToTLMessage(rs.getBytes(1)))
@ -116,10 +111,9 @@ class Database private constructor(var client: TelegramClient) {
} }
val messagesFromUserCount: Int fun getMessagesFromUserCount(): Int {
get() {
try { try {
val rs = stmt!!.executeQuery("SELECT COUNT(*) FROM messages WHERE sender_id=" + user_manager.getUser().getId()) val rs = stmt!!.executeQuery("SELECT COUNT(*) FROM messages WHERE sender_id=" + user_manager.user!!.getId())
rs.next() rs.next()
return rs.getInt(1) return rs.getInt(1)
} catch (e: SQLException) { } catch (e: SQLException) {
@ -128,15 +122,12 @@ class Database private constructor(var client: TelegramClient) {
} }
val messageTypesWithCount: HashMap<String, Integer> fun getMessageTypesWithCount(): HashMap<String, Int> = getMessageTypesWithCount(GlobalChat())
get() = getMessageTypesWithCount(GlobalChat())
val messageMediaTypesWithCount: HashMap<String, Integer> fun getMessageMediaTypesWithCount(): HashMap<String, Int> = getMessageMediaTypesWithCount(GlobalChat())
get() = getMessageMediaTypesWithCount(GlobalChat())
val messageApiLayerWithCount: HashMap<String, Integer> fun getMessageApiLayerWithCount(): HashMap<String, Int> {
get() { val map = HashMap<String, Int>()
val map = HashMap<String, Integer>()
try { try {
val rs = stmt!!.executeQuery("SELECT COUNT(id), api_layer FROM messages GROUP BY api_layer ORDER BY api_layer") val rs = stmt!!.executeQuery("SELECT COUNT(id), api_layer FROM messages GROUP BY api_layer ORDER BY api_layer")
while (rs.next()) { while (rs.next()) {
@ -149,17 +140,13 @@ class Database private constructor(var client: TelegramClient) {
} catch (e: Exception) { } catch (e: Exception) {
throw RuntimeException(e) throw RuntimeException(e)
} }
} }
val messageAuthorsWithCount: HashMap<String, Object> fun getMessageAuthorsWithCount(): HashMap<String, Any> = getMessageAuthorsWithCount(GlobalChat())
get() = getMessageAuthorsWithCount(GlobalChat())
val messageTimesMatrix: Array<IntArray> fun getMessageTimesMatrix(): Array<IntArray> = getMessageTimesMatrix(GlobalChat())
get() = getMessageTimesMatrix(GlobalChat())
val encoding: String fun getEncoding(): String {
get() {
try { try {
val rs = stmt!!.executeQuery("PRAGMA encoding") val rs = stmt!!.executeQuery("PRAGMA encoding")
rs.next() rs.next()
@ -172,8 +159,7 @@ class Database private constructor(var client: TelegramClient) {
} }
val listOfChatsForExport: LinkedList<Chat> fun getListOfChatsForExport(): LinkedList<Chat> {
get() {
val list = LinkedList<Chat>() val list = LinkedList<Chat>()
try { try {
val rs = stmt!!.executeQuery("SELECT chats.id, chats.name, COUNT(messages.id) as c " + val rs = stmt!!.executeQuery("SELECT chats.id, chats.name, COUNT(messages.id) as c " +
@ -192,8 +178,7 @@ class Database private constructor(var client: TelegramClient) {
} }
val listOfDialogsForExport: LinkedList<Dialog> fun getListOfDialogsForExport(): LinkedList<Dialog> {
get() {
val list = LinkedList<Dialog>() val list = LinkedList<Dialog>()
try { try {
val rs = stmt!!.executeQuery( val rs = stmt!!.executeQuery(
@ -221,9 +206,7 @@ class Database private constructor(var client: TelegramClient) {
CommandLineController.show_error("Could not load jdbc-sqlite class.") CommandLineController.show_error("Could not load jdbc-sqlite class.")
} }
val path = "jdbc:sqlite:" + val path = "jdbc:sqlite:${user_manager.fileBase}${Config.FILE_NAME_DB}"
user_manager.getFileBase() +
Config.FILE_NAME_DB
try { try {
conn = DriverManager.getConnection(path) conn = DriverManager.getConnection(path)
@ -233,7 +216,7 @@ class Database private constructor(var client: TelegramClient) {
} }
// Run updates // Run updates
val updates = DatabaseUpdates(conn, this) val updates = DatabaseUpdates(conn!!, this)
updates.doUpdates() updates.doUpdates()
System.out.println("Database is ready.") System.out.println("Database is ready.")
@ -243,8 +226,8 @@ class Database private constructor(var client: TelegramClient) {
val filename = String.format(Config.FILE_NAME_DB_BACKUP, currentVersion) val filename = String.format(Config.FILE_NAME_DB_BACKUP, currentVersion)
System.out.println(" Creating a backup of your database as " + filename) System.out.println(" Creating a backup of your database as " + filename)
try { try {
val src = user_manager.getFileBase() + Config.FILE_NAME_DB val src = user_manager.fileBase + Config.FILE_NAME_DB
val dst = user_manager.getFileBase() + filename val dst = user_manager.fileBase + filename
logger.debug("Copying {} to {}", src, dst) logger.debug("Copying {} to {}", src, dst)
Files.copy( Files.copy(
File(src).toPath(), File(src).toPath(),
@ -289,7 +272,7 @@ class Database private constructor(var client: TelegramClient) {
} }
@Synchronized @Synchronized
fun saveMessages(all: TLVector<TLAbsMessage>, api_layer: Integer) { fun saveMessages(all: TLVector<TLAbsMessage>, api_layer: Int) {
try { try {
//"(id, dialog_id, from_id, from_type, text, time, has_media, data, sticker, type) " + //"(id, dialog_id, from_id, from_type, text, time, has_media, data, sticker, type) " +
//"VALUES " + //"VALUES " +
@ -312,16 +295,16 @@ class Database private constructor(var client: TelegramClient) {
ps.setInt(4, (peer as TLPeerChat).getChatId()) ps.setInt(4, (peer as TLPeerChat).getChatId())
} else if (peer is TLPeerUser) { } else if (peer is TLPeerUser) {
var id = (peer as TLPeerUser).getUserId() var id = (peer as TLPeerUser).getUserId()
if (id == this.user_manager.getUser().getId()) { if (id == this.user_manager.user!!.getId()) {
id = msg.getFromId() id = msg.getFromId()
} }
ps.setString(3, "dialog") ps.setString(3, "dialog")
ps.setInt(4, id) ps.setInt(4, id)
} else if (peer is TLPeerChannel) { } else if (peer is TLPeerChannel) {
ps.setString(3, "channel") ps.setString(3, "channel")
ps.setInt(4, (peer as TLPeerChannel).getChannelId()) ps.setInt(4, peer.getChannelId())
} else { } else {
throw RuntimeException("Unexpected Peer type: " + peer.getClass().getName()) throw RuntimeException("Unexpected Peer type: " + peer.javaClass)
} }
if (peer is TLPeerChannel) { if (peer is TLPeerChannel) {
@ -355,9 +338,9 @@ class Database private constructor(var client: TelegramClient) {
ps.setNull(12, Types.INTEGER) ps.setNull(12, Types.INTEGER)
} else { } else {
ps.setBoolean(9, true) ps.setBoolean(9, true)
ps.setString(10, f!!.getName()) ps.setString(10, f.name)
ps.setString(11, f!!.getTargetFilename()) ps.setString(11, f.targetFilename)
ps.setInt(12, f!!.getSize()) ps.setInt(12, f.size)
} }
val stream = ByteArrayOutputStream() val stream = ByteArrayOutputStream()
msg.serializeBody(stream) msg.serializeBody(stream)
@ -397,7 +380,7 @@ class Database private constructor(var client: TelegramClient) {
ps_insert_or_ignore.setInt(14, api_layer) ps_insert_or_ignore.setInt(14, api_layer)
ps_insert_or_ignore.addBatch() ps_insert_or_ignore.addBatch()
} else { } else {
throw RuntimeException("Unexpected Message type: " + abs.getClass().getName()) throw RuntimeException("Unexpected Message type: " + abs.javaClass)
} }
} }
conn!!.setAutoCommit(false) conn!!.setAutoCommit(false)
@ -452,7 +435,7 @@ class Database private constructor(var client: TelegramClient) {
ps_insert_or_replace.setString(3, "channel") ps_insert_or_replace.setString(3, "channel")
ps_insert_or_replace.addBatch() ps_insert_or_replace.addBatch()
} else { } else {
throw RuntimeException("Unexpected " + abs.getClass().getName()) throw RuntimeException("Unexpected " + abs.javaClass)
} }
} }
conn!!.setAutoCommit(false) conn!!.setAutoCommit(false)
@ -501,7 +484,7 @@ class Database private constructor(var client: TelegramClient) {
ps_insert_or_ignore.setNull(6, Types.VARCHAR) ps_insert_or_ignore.setNull(6, Types.VARCHAR)
ps_insert_or_ignore.addBatch() ps_insert_or_ignore.addBatch()
} else { } else {
throw RuntimeException("Unexpected " + abs.getClass().getName()) throw RuntimeException("Unexpected " + abs.javaClass)
} }
} }
conn!!.setAutoCommit(false) conn!!.setAutoCommit(false)
@ -518,9 +501,9 @@ class Database private constructor(var client: TelegramClient) {
} }
fun getIdsFromQuery(query: String): LinkedList<Integer> { fun getIdsFromQuery(query: String): LinkedList<Int> {
try { try {
val list = LinkedList<Integer>() val list = LinkedList<Int>()
val rs = stmt!!.executeQuery(query) val rs = stmt!!.executeQuery(query)
while (rs.next()) { while (rs.next()) {
list.add(rs.getInt(1)) list.add(rs.getInt(1))
@ -533,8 +516,8 @@ class Database private constructor(var client: TelegramClient) {
} }
fun getMessageTypesWithCount(c: AbstractChat): HashMap<String, Integer> { fun getMessageTypesWithCount(c: AbstractChat): HashMap<String, Int> {
val map = HashMap<String, Integer>() val map = HashMap<String, Int>()
try { try {
val rs = stmt!!.executeQuery("SELECT message_type, COUNT(message_id) FROM messages WHERE " + c.query + " GROUP BY message_type") val rs = stmt!!.executeQuery("SELECT message_type, COUNT(message_id) FROM messages WHERE " + c.query + " GROUP BY message_type")
while (rs.next()) { while (rs.next()) {
@ -547,8 +530,8 @@ class Database private constructor(var client: TelegramClient) {
} }
fun getMessageMediaTypesWithCount(c: AbstractChat): HashMap<String, Integer> { fun getMessageMediaTypesWithCount(c: AbstractChat): HashMap<String, Int> {
val map = HashMap<String, Integer>() val map = HashMap<String, Int>()
try { try {
var count = 0 var count = 0
val rs = stmt!!.executeQuery("SELECT media_type, COUNT(message_id) FROM messages WHERE " + c.query + " GROUP BY media_type") val rs = stmt!!.executeQuery("SELECT media_type, COUNT(message_id) FROM messages WHERE " + c.query + " GROUP BY media_type")
@ -569,9 +552,9 @@ class Database private constructor(var client: TelegramClient) {
} }
fun getMessageAuthorsWithCount(c: AbstractChat): HashMap<String, Object> { fun getMessageAuthorsWithCount(c: AbstractChat): HashMap<String, Any> {
val map = HashMap<String, Object>() val map = HashMap<String, Any>()
val user_map = HashMap<User, Integer>() val user_map = HashMap<User, Int>()
var count_others = 0 var count_others = 0
// Set a default value for 'me' to fix the charts for channels - cause I // Set a default value for 'me' to fix the charts for channels - cause I
// possibly didn't send any messages there. // possibly didn't send any messages there.
@ -596,7 +579,7 @@ class Database private constructor(var client: TelegramClient) {
} }
} }
map.put("authors.count.others", count_others) map.put("authors.count.others", count_others)
map.put("authors.all", user_map.entrySet()) map.put("authors.all", user_map)
return map return map
} catch (e: Exception) { } catch (e: Exception) {
throw RuntimeException(e) throw RuntimeException(e)
@ -621,7 +604,7 @@ class Database private constructor(var client: TelegramClient) {
} }
fun getMessagesForExport(c: AbstractChat): LinkedList<HashMap<String, Object>> { fun getMessagesForExport(c: AbstractChat): LinkedList<HashMap<String, Any>> {
try { try {
val rs = stmt!!.executeQuery("SELECT messages.message_id as message_id, text, time*1000 as time, has_media, " + val rs = stmt!!.executeQuery("SELECT messages.message_id as message_id, text, time*1000 as time, has_media, " +
@ -637,13 +620,13 @@ class Database private constructor(var client: TelegramClient) {
val format_date = SimpleDateFormat("d MMM yy") val format_date = SimpleDateFormat("d MMM yy")
val meta = rs.getMetaData() val meta = rs.getMetaData()
val columns = meta.getColumnCount() val columns = meta.getColumnCount()
val list = LinkedList<HashMap<String, Object>>() val list = LinkedList<HashMap<String, Any>>()
var count: Integer = 0 var count = 0
var old_date: String? = null var old_date: String? = null
var old_user: Integer? = null var old_user = 0
while (rs.next()) { while (rs.next()) {
val h = HashMap<String, Object>(columns) val h = HashMap<String, Any>(columns)
for (i in 1..columns) { for (i in 1..columns) {
h.put(meta.getColumnName(i), rs.getObject(i)) h.put(meta.getColumnName(i), rs.getObject(i))
} }
@ -655,7 +638,7 @@ class Database private constructor(var client: TelegramClient) {
if (rs.getString("media_type") != null) { if (rs.getString("media_type") != null) {
h.put("media_" + rs.getString("media_type"), true) h.put("media_" + rs.getString("media_type"), true)
} }
h.put("from_me", rs.getInt("user_id") === user_manager.getUser().getId()) h.put("from_me", rs.getInt("user_id") === user_manager.user!!.getId())
h.put("is_new_date", !date.equals(old_date)) h.put("is_new_date", !date.equals(old_date))
h.put("odd_even", if (count % 2 == 0) "even" else "odd") h.put("odd_even", if (count % 2 == 0) "even" else "odd")
h.put("same_user", old_user != null && rs.getInt("user_id") === old_user) h.put("same_user", old_user != null && rs.getInt("user_id") === old_user)
@ -696,7 +679,7 @@ class Database private constructor(var client: TelegramClient) {
var isMe: Boolean = false var isMe: Boolean = false
init { init {
isMe = id == user_manager.getUser().getId() isMe = id == user_manager.user!!.getId()
val s = StringBuilder() val s = StringBuilder()
if (first_name != null) s.append(first_name + " ") if (first_name != null) s.append(first_name + " ")
if (last_name != null) s.append(last_name) if (last_name != null) s.append(last_name)
@ -711,7 +694,7 @@ class Database private constructor(var client: TelegramClient) {
companion object { companion object {
private val logger = LoggerFactory.getLogger(Database::class.java) private val logger = LoggerFactory.getLogger(Database::class.java)
private var instance: Database? = null internal var instance: Database? = null
fun init(c: TelegramClient) { fun init(c: TelegramClient) {
instance = Database(c) instance = Database(c)
@ -719,7 +702,7 @@ class Database private constructor(var client: TelegramClient) {
fun getInstance(): Database { fun getInstance(): Database {
if (instance == null) throw RuntimeException("Database is not initialized but getInstance() was called.") if (instance == null) throw RuntimeException("Database is not initialized but getInstance() was called.")
return instance return instance!!
} }
fun bytesToTLMessage(b: ByteArray?): TLMessage? { fun bytesToTLMessage(b: ByteArray?): TLMessage? {

View File

@ -18,7 +18,7 @@ import de.fabianonline.telegram_backup.mediafilemanager.AbstractMediaFileManager
class DatabaseUpdates(protected var conn: Connection, protected var db: Database) { class DatabaseUpdates(protected var conn: Connection, protected var db: Database) {
private val maxPossibleVersion: Int private val maxPossibleVersion: Int
get() = updates.size() get() = updates.size
init { init {
logger.debug("Registering Database Updates...") logger.debug("Registering Database Updates...")
@ -62,7 +62,7 @@ class DatabaseUpdates(protected var conn: Connection, protected var db: Database
logger.debug("Update is necessary. {} => {}.", version, maxPossibleVersion) logger.debug("Update is necessary. {} => {}.", version, maxPossibleVersion)
var backup = false var backup = false
for (i in version + 1..maxPossibleVersion) { for (i in version + 1..maxPossibleVersion) {
if (getUpdateToVersion(i).needsBackup()) { if (getUpdateToVersion(i).needsBackup) {
logger.debug("Update to version {} needs a backup", i) logger.debug("Update to version {} needs a backup", i)
backup = true backup = true
} }
@ -100,9 +100,9 @@ class DatabaseUpdates(protected var conn: Connection, protected var db: Database
} }
private fun register(d: DatabaseUpdate) { private fun register(d: DatabaseUpdate) {
logger.debug("Registering {} as update to version {}", d.getClass().getName(), d.version) logger.debug("Registering {} as update to version {}", d.javaClass, d.version)
if (d.version != updates.size() + 1) { if (d.version != updates.size + 1) {
throw RuntimeException("Tried to register DB update to version " + d.version + ", but would need update to version " + (updates.size() + 1)) throw RuntimeException("Tried to register DB update to version ${d.version}, but would need update to version ${updates.size + 1}")
} }
updates.add(d) updates.add(d)
} }
@ -138,9 +138,7 @@ internal abstract class DatabaseUpdate(protected var conn: Connection, protected
@Throws(SQLException::class) @Throws(SQLException::class)
protected abstract fun _doUpdate() protected abstract fun _doUpdate()
fun needsBackup(): Boolean { open val needsBackup = false
return false
}
@Throws(SQLException::class) @Throws(SQLException::class)
protected fun execute(sql: String) { protected fun execute(sql: String) {
@ -233,9 +231,7 @@ internal class DB_Update_6(conn: Connection, db: Database) : DatabaseUpdate(conn
override val version: Int override val version: Int
get() = 6 get() = 6
override fun needsBackup(): Boolean { override val needsBackup = true
return true
}
@Throws(SQLException::class) @Throws(SQLException::class)
override fun _doUpdate() { override fun _doUpdate() {
@ -269,14 +265,14 @@ internal class DB_Update_6(conn: Connection, db: Database) : DatabaseUpdate(conn
val query = StringBuilder("INSERT INTO messages_new\n(") val query = StringBuilder("INSERT INTO messages_new\n(")
var first: Boolean var first: Boolean
first = true first = true
for (s in mappings.keySet()) { for (s in mappings.keys) {
if (!first) query.append(", ") if (!first) query.append(", ")
query.append(s) query.append(s)
first = false first = false
} }
query.append(")\nSELECT \n") query.append(")\nSELECT \n")
first = true first = true
for (s in mappings.values()) { for (s in mappings.values) {
if (!first) query.append(", ") if (!first) query.append(", ")
query.append(s) query.append(s)
first = false first = false
@ -289,7 +285,7 @@ internal class DB_Update_6(conn: Connection, db: Database) : DatabaseUpdate(conn
val ps = conn.prepareStatement("UPDATE messages_new SET fwd_from_id=?, media_type=?, media_file=?, media_size=? WHERE id=?") val ps = conn.prepareStatement("UPDATE messages_new SET fwd_from_id=?, media_type=?, media_file=?, media_size=? WHERE id=?")
while (rs.next()) { while (rs.next()) {
ps.setInt(5, rs.getInt(1)) ps.setInt(5, rs.getInt(1))
val msg = db.bytesToTLMessage(rs.getBytes(2)) val msg = Database.bytesToTLMessage(rs.getBytes(2))
if (msg == null || msg!!.getFwdFrom() == null) { if (msg == null || msg!!.getFwdFrom() == null) {
ps.setNull(1, Types.INTEGER) ps.setNull(1, Types.INTEGER)
} else { } else {
@ -301,9 +297,9 @@ internal class DB_Update_6(conn: Connection, db: Database) : DatabaseUpdate(conn
ps.setNull(3, Types.VARCHAR) ps.setNull(3, Types.VARCHAR)
ps.setNull(4, Types.INTEGER) ps.setNull(4, Types.INTEGER)
} else { } else {
ps.setString(2, f!!.getName()) ps.setString(2, f.name)
ps.setString(3, f!!.getTargetFilename()) ps.setString(3, f.targetFilename)
ps.setInt(4, f!!.getSize()) ps.setInt(4, f.size)
} }
ps.addBatch() ps.addBatch()
} }
@ -321,9 +317,7 @@ internal class DB_Update_7(conn: Connection, db: Database) : DatabaseUpdate(conn
override val version: Int override val version: Int
get() = 7 get() = 7
override fun needsBackup(): Boolean { override val needsBackup = true
return true
}
@Throws(SQLException::class) @Throws(SQLException::class)
override fun _doUpdate() { override fun _doUpdate() {
@ -337,9 +331,7 @@ internal class DB_Update_8(conn: Connection, db: Database) : DatabaseUpdate(conn
override val version: Int override val version: Int
get() = 8 get() = 8
override fun needsBackup(): Boolean { override val needsBackup = true
return true
}
@Throws(SQLException::class) @Throws(SQLException::class)
override fun _doUpdate() { override fun _doUpdate() {

View File

@ -65,7 +65,7 @@ class DownloadManager(internal var client: TelegramClient?, p: DownloadProgressI
} }
@Throws(RpcErrorException::class, IOException::class) @Throws(RpcErrorException::class, IOException::class)
fun downloadMessages(limit: Integer) { fun downloadMessages(limit: Int?) {
var completed = true var completed = true
do { do {
completed = true completed = true
@ -95,7 +95,7 @@ class DownloadManager(internal var client: TelegramClient?, p: DownloadProgressI
} }
@Throws(RpcErrorException::class, IOException::class, TimeoutException::class) @Throws(RpcErrorException::class, IOException::class, TimeoutException::class)
fun _downloadMessages(limit: Integer?) { fun _downloadMessages(limit: Int?) {
logger.info("This is _downloadMessages with limit {}", limit) logger.info("This is _downloadMessages with limit {}", limit)
val dialog_limit = 100 val dialog_limit = 100
logger.info("Downloading the last {} dialogs", dialog_limit) logger.info("Downloading the last {} dialogs", dialog_limit)
@ -106,11 +106,11 @@ class DownloadManager(internal var client: TelegramClient?, p: DownloadProgressI
0, 0,
TLInputPeerEmpty(), TLInputPeerEmpty(),
dialog_limit) dialog_limit)
logger.debug("Got {} dialogs", dialogs.getDialogs().size()) logger.debug("Got {} dialogs", dialogs.getDialogs().size)
for (d in dialogs.getDialogs()) { for (d in dialogs.getDialogs()) {
if (d.getTopMessage() > max_message_id && d.getPeer() !is TLPeerChannel) { if (d.getTopMessage() > max_message_id && d.getPeer() !is TLPeerChannel) {
logger.trace("Updating top message id: {} => {}. Dialog type: {}", max_message_id, d.getTopMessage(), d.getPeer().getClass().getName()) logger.trace("Updating top message id: {} => {}. Dialog type: {}", max_message_id, d.getTopMessage(), d.getPeer().javaClass)
max_message_id = d.getTopMessage() max_message_id = d.getTopMessage()
} }
} }
@ -174,10 +174,10 @@ class DownloadManager(internal var client: TelegramClient?, p: DownloadProgressI
System.out.println("Processing channels and/or supergroups...") System.out.println("Processing channels and/or supergroups...")
System.out.println("Please note that only channels/supergroups in the last 100 active chats are processed.") System.out.println("Please note that only channels/supergroups in the last 100 active chats are processed.")
val channel_access_hashes = HashMap<Integer, Long>() val channel_access_hashes = HashMap<Int, Long>()
val channel_names = HashMap<Integer, String>() val channel_names = HashMap<Int, String>()
val channels = LinkedList<Integer>() val channels = LinkedList<Int>()
val supergroups = LinkedList<Integer>() val supergroups = LinkedList<Int>()
// TODO Add chat title (and other stuff?) to the database // TODO Add chat title (and other stuff?) to the database
for (c in dialogs.getChats()) { for (c in dialogs.getChats()) {
@ -224,21 +224,21 @@ class DownloadManager(internal var client: TelegramClient?, p: DownloadProgressI
} }
@Throws(RpcErrorException::class, IOException::class) @Throws(RpcErrorException::class, IOException::class)
private fun downloadMessages(ids: List<Integer>, channel: TLInputChannel?, source_string: String?) { private fun downloadMessages(ids: MutableList<Int>, channel: TLInputChannel?, source_string: String?) {
prog!!.onMessageDownloadStart(ids.size(), source_string) prog!!.onMessageDownloadStart(ids.size, source_string)
logger.debug("Entering download loop") logger.debug("Entering download loop")
while (ids.size() > 0) { while (ids.size > 0) {
logger.trace("Loop") logger.trace("Loop")
val vector = TLIntVector() val vector = TLIntVector()
val download_count = Config.GET_MESSAGES_BATCH_SIZE val download_count = Config.GET_MESSAGES_BATCH_SIZE
logger.trace("download_count: {}", download_count) logger.trace("download_count: {}", download_count)
for (i in 0 until download_count) { for (i in 0 until download_count) {
if (ids.size() === 0) break if (ids.size === 0) break
vector.add(ids.remove(0)) vector.add(ids.removeAt(0))
} }
logger.trace("vector.size(): {}", vector.size()) logger.trace("vector.size(): {}", vector.size)
logger.trace("ids.size(): {}", ids.size()) logger.trace("ids.size(): {}", ids.size)
var response: TLAbsMessages var response: TLAbsMessages
var tries = 0 var tries = 0
@ -265,12 +265,12 @@ class DownloadManager(internal var client: TelegramClient?, p: DownloadProgressI
} }
} }
logger.trace("response.getMessages().size(): {}", response.getMessages().size()) logger.trace("response.getMessages().size(): {}", response.getMessages().size)
if (response.getMessages().size() !== vector.size()) { if (response.getMessages().size !== vector.size) {
CommandLineController.show_error("Requested " + vector.size() + " messages, but got " + response.getMessages().size() + ". That is unexpected. Quitting.") CommandLineController.show_error("Requested ${vector.size} messages, but got ${response.getMessages().size}. That is unexpected. Quitting.")
} }
prog!!.onMessageDownloaded(response.getMessages().size()) prog!!.onMessageDownloaded(response.getMessages().size)
db!!.saveMessages(response.getMessages(), Kotlogram.API_LAYER) db!!.saveMessages(response.getMessages(), Kotlogram.API_LAYER)
db!!.saveChats(response.getChats()) db!!.saveChats(response.getChats())
db!!.saveUsers(response.getUsers()) db!!.saveUsers(response.getUsers())
@ -319,26 +319,27 @@ class DownloadManager(internal var client: TelegramClient?, p: DownloadProgressI
logger.info("This is _downloadMedia") logger.info("This is _downloadMedia")
logger.info("Checking if there are messages in the DB with a too old API layer") logger.info("Checking if there are messages in the DB with a too old API layer")
val ids = db!!.getIdsFromQuery("SELECT id FROM messages WHERE has_media=1 AND api_layer<" + Kotlogram.API_LAYER) val ids = db!!.getIdsFromQuery("SELECT id FROM messages WHERE has_media=1 AND api_layer<" + Kotlogram.API_LAYER)
if (ids.size() > 0) { if (ids.size > 0) {
System.out.println("You have " + ids.size() + " messages in your db that need an update. Doing that now.") System.out.println("You have ${ids.size} messages in your db that need an update. Doing that now.")
logger.debug("Found {} messages", ids.size()) logger.debug("Found {} messages", ids.size)
downloadMessages(ids, null, null) downloadMessages(ids, null, null)
} }
val messages = this.db!!.getMessagesWithMedia() val messages = this.db!!.getMessagesWithMedia()
logger.debug("Database returned {} messages with media", messages.size()) logger.debug("Database returned {} messages with media", messages.size)
prog!!.onMediaDownloadStart(messages.size()) prog!!.onMediaDownloadStart(messages.size)
for (msg in messages) { for (msg in messages) {
val m = FileManagerFactory.getFileManager(msg, user, client) if (msg==null) continue
val m = FileManagerFactory.getFileManager(msg, user!!, client!!)
logger.trace("message {}, {}, {}, {}, {}", logger.trace("message {}, {}, {}, {}, {}",
msg.getId(), msg.getId(),
msg.getMedia().getClass().getSimpleName().replace("TLMessageMedia", ""), msg.getMedia().javaClass.getSimpleName().replace("TLMessageMedia", ""),
m.getClass().getSimpleName(), m!!.javaClass.getSimpleName(),
if (m.isEmpty()) "empty" else "non-empty", if (m.isEmpty) "empty" else "non-empty",
if (m.isDownloaded()) "downloaded" else "not downloaded") if (m.downloaded) "downloaded" else "not downloaded")
if (m.isEmpty()) { if (m.isEmpty) {
prog!!.onMediaDownloadedEmpty() prog!!.onMediaDownloadedEmpty()
} else if (m.isDownloaded()) { } else if (m.downloaded) {
prog!!.onMediaAlreadyPresent(m) prog!!.onMediaAlreadyPresent(m)
} else { } else {
try { try {
@ -354,8 +355,8 @@ class DownloadManager(internal var client: TelegramClient?, p: DownloadProgressI
prog!!.onMediaDownloadFinished() prog!!.onMediaDownloadFinished()
} }
private fun makeIdList(start: Int, end: Int): List<Integer> { private fun makeIdList(start: Int, end: Int): MutableList<Int> {
val a = LinkedList<Integer>() val a = LinkedList<Int>()
for (i in start..end) a.add(i) for (i in start..end) a.add(i)
return a return a
} }
@ -378,7 +379,7 @@ class DownloadManager(internal var client: TelegramClient?, p: DownloadProgressI
} }
@Throws(RpcErrorException::class, IOException::class, TimeoutException::class) @Throws(RpcErrorException::class, IOException::class, TimeoutException::class)
private fun downloadFileFromDc(client: TelegramClient, target: String, loc: TLAbsInputFileLocation, dcID: Integer?, size: Int): Boolean { private fun downloadFileFromDc(client: TelegramClient, target: String, loc: TLAbsInputFileLocation, dcID: Int, size: Int): Boolean {
var fos: FileOutputStream? = null var fos: FileOutputStream? = null
try { try {
val temp_filename = target + ".downloading" val temp_filename = target + ".downloading"
@ -388,7 +389,7 @@ class DownloadManager(internal var client: TelegramClient?, p: DownloadProgressI
var offset = 0 var offset = 0
if (File(temp_filename).isFile()) { if (File(temp_filename).isFile()) {
logger.info("Temporary filename already exists; continuing this file") logger.info("Temporary filename already exists; continuing this file")
offset = File(temp_filename).length() offset = File(temp_filename).length() as Int
if (offset >= size) { if (offset >= size) {
logger.warn("Temporary file size is >= the target size. Assuming corrupt file & deleting it") logger.warn("Temporary file size is >= the target size. Assuming corrupt file & deleting it")
File(temp_filename).delete() File(temp_filename).delete()
@ -422,8 +423,8 @@ class DownloadManager(internal var client: TelegramClient?, p: DownloadProgressI
} }
} }
offset += response!!.getBytes().getData().length offset += response!!.getBytes().getData().size
logger.trace("response: {} total size: {}", response!!.getBytes().getData().length, offset) logger.trace("response: {} total size: {}", response!!.getBytes().getData().size, offset)
fos!!.write(response!!.getBytes().getData()) fos!!.write(response!!.getBytes().getData())
fos!!.flush() fos!!.flush()
@ -432,7 +433,7 @@ class DownloadManager(internal var client: TelegramClient?, p: DownloadProgressI
} catch (e: InterruptedException) { } catch (e: InterruptedException) {
} }
} while (offset < size && (response!!.getBytes().getData().length > 0 || try_again)) } while (offset < size && (response!!.getBytes().getData().size > 0 || try_again))
fos!!.close() fos!!.close()
if (offset < size) { if (offset < size) {
System.out.println("Requested file $target with $size bytes, but got only $offset bytes.") System.out.println("Requested file $target with $size bytes, but got only $offset bytes.")

View File

@ -19,7 +19,7 @@ package de.fabianonline.telegram_backup
import de.fabianonline.telegram_backup.mediafilemanager.AbstractMediaFileManager import de.fabianonline.telegram_backup.mediafilemanager.AbstractMediaFileManager
interface DownloadProgressInterface { interface DownloadProgressInterface {
fun onMessageDownloadStart(count: Int, source: String) fun onMessageDownloadStart(count: Int, source: String?)
fun onMessageDownloaded(number: Int) fun onMessageDownloaded(number: Int)
fun onMessageDownloadFinished() fun onMessageDownloadFinished()

View File

@ -24,7 +24,7 @@ import java.awt.event.ActionEvent
import java.awt.event.ActionListener import java.awt.event.ActionListener
import java.util.Vector import java.util.Vector
class GUIController { class GUIController() {
init { init {
showAccountChooserDialog() showAccountChooserDialog()
} }
@ -50,22 +50,6 @@ class GUIController {
accountChooser.add(vert) accountChooser.add(vert)
accountChooser.setVisible(true) accountChooser.setVisible(true)
accountChooser.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE) accountChooser.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE)
list.addListSelectionListener(object : ListSelectionListener() {
@Override
fun valueChanged(e: ListSelectionEvent) {
btnLogin.setEnabled(true)
}
})
btnAddAccount.addActionListener(object : ActionListener() {
@Override
fun actionPerformed(e: ActionEvent) {
accountChooser.setVisible(false)
accountChooser.dispose()
addAccountDialog()
}
})
} }
private fun addAccountDialog() { private fun addAccountDialog() {

View File

@ -28,16 +28,15 @@ import com.github.badoualy.telegram.tl.StreamUtils.readTLObject
class TLRequestAccountGetPasswordWithCurrentSalt : TLMethod<TLPassword>() { class TLRequestAccountGetPasswordWithCurrentSalt : TLMethod<TLPassword>() {
private val _constructor = "account.getPassword#548a30f5" private val _constructor = "account.getPassword#548a30f5"
val constructorId: Int override fun getConstructorId(): Int = CONSTRUCTOR_ID
get() = CONSTRUCTOR_ID
@Throws(IOException::class) @Throws(IOException::class)
fun deserializeResponse(stream: InputStream, context: TLContext): TLPassword { override fun deserializeResponse(stream: InputStream, context: TLContext): TLPassword {
val response = (readTLObject(stream, context) ?: throw IOException("Unable to parse response")) as? TLPassword ?: throw IOException("Incorrect response type, expected getClass().getCanonicalName(), found response.getClass().getCanonicalName()") val response = (readTLObject(stream, context) ?: throw IOException("Unable to parse response")) as? TLPassword ?: throw IOException("Incorrect response type, expected getClass().getCanonicalName(), found response.getClass().getCanonicalName()")
return response as TLPassword return response as TLPassword
} }
fun toString(): String { override fun toString(): String {
return _constructor return _constructor
} }

View File

@ -37,18 +37,18 @@ internal class TelegramUpdateHandler : UpdateCallback {
this.db = Database.getInstance() this.db = Database.getInstance()
} }
fun onUpdates(c: TelegramClient, u: TLUpdates) { override fun onUpdates(c: TelegramClient, u: TLUpdates) {
if (db == null) return if (db == null) return
if (debug) System.out.println("onUpdates - " + u.getUpdates().size() + " Updates, " + u.getUsers().size() + " Users, " + u.getChats().size() + " Chats") if (debug) System.out.println("onUpdates - " + u.getUpdates().size + " Updates, " + u.getUsers().size + " Users, " + u.getChats().size + " Chats")
for (update in u.getUpdates()) { for (update in u.getUpdates()) {
processUpdate(update, c) processUpdate(update, c)
if (debug) System.out.println(" " + update.getClass().getName()) if (debug) System.out.println(" " + update.javaClass.getName())
} }
db!!.saveUsers(u.getUsers()) db!!.saveUsers(u.getUsers())
db!!.saveChats(u.getChats()) db!!.saveChats(u.getChats())
} }
fun onUpdatesCombined(c: TelegramClient, u: TLUpdatesCombined) { override fun onUpdatesCombined(c: TelegramClient, u: TLUpdatesCombined) {
if (db == null) return if (db == null) return
if (debug) System.out.println("onUpdatesCombined") if (debug) System.out.println("onUpdatesCombined")
for (update in u.getUpdates()) { for (update in u.getUpdates()) {
@ -58,14 +58,14 @@ internal class TelegramUpdateHandler : UpdateCallback {
db!!.saveChats(u.getChats()) db!!.saveChats(u.getChats())
} }
fun onUpdateShort(c: TelegramClient, u: TLUpdateShort) { override fun onUpdateShort(c: TelegramClient, u: TLUpdateShort) {
if (db == null) return if (db == null) return
if (debug) System.out.println("onUpdateShort") if (debug) System.out.println("onUpdateShort")
processUpdate(u.getUpdate(), c) processUpdate(u.getUpdate(), c)
if (debug) System.out.println(" " + u.getUpdate().getClass().getName()) if (debug) System.out.println(" " + u.getUpdate().javaClass.getName())
} }
fun onShortChatMessage(c: TelegramClient, m: TLUpdateShortChatMessage) { override fun onShortChatMessage(c: TelegramClient, m: TLUpdateShortChatMessage) {
if (db == null) return if (db == null) return
if (debug) System.out.println("onShortChatMessage - " + m.getMessage()) if (debug) System.out.println("onShortChatMessage - " + m.getMessage())
val msg = TLMessage( val msg = TLMessage(
@ -89,16 +89,16 @@ internal class TelegramUpdateHandler : UpdateCallback {
System.out.print('.') System.out.print('.')
} }
fun onShortMessage(c: TelegramClient, m: TLUpdateShortMessage) { override fun onShortMessage(c: TelegramClient, m: TLUpdateShortMessage) {
if (db == null) return if (db == null) return
if (debug) System.out.println("onShortMessage - " + m.getOut() + " - " + m.getUserId() + " - " + m.getMessage()) if (debug) System.out.println("onShortMessage - " + m.getOut() + " - " + m.getUserId() + " - " + m.getMessage())
val from_id: Int val from_id: Int
val to_id: Int val to_id: Int
if (m.getOut() === true) { if (m.getOut() === true) {
from_id = user!!.getUser().getId() from_id = user!!.user!!.getId()
to_id = m.getUserId() to_id = m.getUserId()
} else { } else {
to_id = user!!.getUser().getId() to_id = user!!.user!!.getId()
from_id = m.getUserId() from_id = m.getUserId()
} }
val msg = TLMessage( val msg = TLMessage(
@ -122,12 +122,12 @@ internal class TelegramUpdateHandler : UpdateCallback {
System.out.print('.') System.out.print('.')
} }
fun onShortSentMessage(c: TelegramClient, m: TLUpdateShortSentMessage) { override fun onShortSentMessage(c: TelegramClient, m: TLUpdateShortSentMessage) {
if (db == null) return if (db == null) return
System.out.println("onShortSentMessage") System.out.println("onShortSentMessage")
} }
fun onUpdateTooLong(c: TelegramClient) { override fun onUpdateTooLong(c: TelegramClient) {
if (db == null) return if (db == null) return
System.out.println("onUpdateTooLong") System.out.println("onUpdateTooLong")
} }
@ -140,8 +140,8 @@ internal class TelegramUpdateHandler : UpdateCallback {
db!!.saveMessages(vector, Kotlogram.API_LAYER) db!!.saveMessages(vector, Kotlogram.API_LAYER)
System.out.print('.') System.out.print('.')
if (abs_msg is TLMessage) { if (abs_msg is TLMessage) {
val fm = FileManagerFactory.getFileManager(abs_msg as TLMessage, user, client) val fm = FileManagerFactory.getFileManager(abs_msg as TLMessage, user!!, client)
if (fm != null && !fm!!.isEmpty() && !fm!!.isDownloaded()) { if (fm != null && !fm!!.isEmpty && !fm!!.downloaded) {
try { try {
fm!!.download() fm!!.download()
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -39,13 +39,13 @@ private constructor(c: TelegramClient) {
var user: TLUser? = null var user: TLUser? = null
var phone: String? = null var phone: String? = null
private var code: String? = null private var code: String? = null
private val client: TelegramClient? = null private val client: TelegramClient
private var sent_code: TLSentCode? = null private var sent_code: TLSentCode? = null
private var auth: TLAuthorization? = null private var auth: TLAuthorization? = null
var isPasswordNeeded = false var isPasswordNeeded = false
private set private set
val isLoggedIn: Boolean val loggedIn: Boolean
get() = user != null get() = user != null
val userString: String val userString: String
@ -86,7 +86,7 @@ private constructor(c: TelegramClient) {
@Throws(RpcErrorException::class, IOException::class) @Throws(RpcErrorException::class, IOException::class)
fun sendCodeToPhoneNumber(number: String) { fun sendCodeToPhoneNumber(number: String) {
this.phone = number this.phone = number
this.sent_code = this.client!!.authSendCode(false, this.phone, true) this.sent_code = this.client!!.authSendCode(false, number, true)
} }
@Throws(RpcErrorException::class, IOException::class) @Throws(RpcErrorException::class, IOException::class)
@ -104,7 +104,7 @@ private constructor(c: TelegramClient) {
@Throws(RpcErrorException::class, IOException::class) @Throws(RpcErrorException::class, IOException::class)
fun verifyPassword(pw: String) { fun verifyPassword(pw: String) {
val password = pw.getBytes("UTF-8") val password = pw.toByteArray(charset=Charsets.UTF_8)
val salt = (client!!.accountGetPassword() as TLPassword).getCurrentSalt().getData() val salt = (client!!.accountGetPassword() as TLPassword).getCurrentSalt().getData()
var md: MessageDigest? = null var md: MessageDigest? = null
try { try {
@ -125,7 +125,7 @@ private constructor(c: TelegramClient) {
companion object { companion object {
private val logger = LoggerFactory.getLogger(UserManager::class.java) private val logger = LoggerFactory.getLogger(UserManager::class.java)
private var instance: UserManager? = null internal var instance: UserManager? = null
@Throws(IOException::class) @Throws(IOException::class)
fun init(c: TelegramClient) { fun init(c: TelegramClient) {
@ -134,7 +134,7 @@ private constructor(c: TelegramClient) {
fun getInstance(): UserManager { fun getInstance(): UserManager {
if (instance == null) throw RuntimeException("UserManager is not yet initialized.") if (instance == null) throw RuntimeException("UserManager is not yet initialized.")
return instance return instance!!
} }
} }
} }

View File

@ -34,8 +34,7 @@ object Utils {
private val logger = LoggerFactory.getLogger(Utils::class.java) as Logger private val logger = LoggerFactory.getLogger(Utils::class.java) as Logger
internal val accounts: Vector<String> fun getAccounts(): Vector<String> {
get() {
val accounts = Vector<String>() val accounts = Vector<String>()
val folder = File(Config.FILE_BASE) val folder = File(Config.FILE_BASE)
val files = folder.listFiles() val files = folder.listFiles()
@ -48,8 +47,7 @@ object Utils {
return accounts return accounts
} }
internal val newestVersion: Version? fun getNewestVersion(): Version? {
get() {
try { try {
val data_url = "https://api.github.com/repos/fabianonline/telegram_backup/releases" val data_url = "https://api.github.com/repos/fabianonline/telegram_backup/releases"
logger.debug("Requesting current release info from {}", data_url) logger.debug("Requesting current release info from {}", data_url)
@ -87,7 +85,7 @@ object Utils {
@JvmOverloads internal fun obeyFloodWaitException(e: RpcErrorException?, silent: Boolean = false) { @JvmOverloads internal fun obeyFloodWaitException(e: RpcErrorException?, silent: Boolean = false) {
if (e == null || e!!.getCode() !== 420) return if (e == null || e!!.getCode() !== 420) return
val delay = e!!.getTagInteger() val delay: Long = e!!.getTagInteger()!! as Long
if (!silent) { if (!silent) {
System.out.println("") System.out.println("")
System.out.println( System.out.println(
@ -112,13 +110,13 @@ object Utils {
logger.debug("Comparing versions {} and {}.", v1, v2) logger.debug("Comparing versions {} and {}.", v1, v2)
if (v1.equals(v2)) return VERSIONS_EQUAL if (v1.equals(v2)) return VERSIONS_EQUAL
val v1_p = v1.split("-", 2) val v1_p = v1.split("-", limit=2)
val v2_p = v2.split("-", 2) val v2_p = v2.split("-", limit=2)
logger.trace("Parts to compare without suffixes: {} and {}.", v1_p[0], v2_p[0]) logger.trace("Parts to compare without suffixes: {} and {}.", v1_p[0], v2_p[0])
val v1_p2 = v1_p[0].split("\\.") val v1_p2 = v1_p[0].split(".")
val v2_p2 = v2_p[0].split("\\.") val v2_p2 = v2_p[0].split(".")
logger.trace("Length of the parts without suffixes: {} and {}.", v1_p2.size, v2_p2.size) logger.trace("Length of the parts without suffixes: {} and {}.", v1_p2.size, v2_p2.size)
@ -179,6 +177,6 @@ object Utils {
} }
fun anonymize(str: String): String { fun anonymize(str: String): String {
return if (!CommandLineOptions.cmd_anonymize) str else str.replaceAll("[0-9]", "1").replaceAll("[A-Z]", "A").replaceAll("[a-z]", "a") + " (ANONYMIZED)" return if (!CommandLineOptions.cmd_anonymize) str else str.replace("[0-9]".toRegex(), "1").replace("[A-Z]".toRegex(), "A").replace("[a-z]".toRegex(), "a") + " (ANONYMIZED)"
} }
} }

View File

@ -50,26 +50,26 @@ class HTMLExporter {
// Create base dir // Create base dir
logger.debug("Creating base dir") logger.debug("Creating base dir")
val base = user.getFileBase() + "files" + File.separatorChar val base = user.fileBase + "files" + File.separatorChar
File(base).mkdirs() File(base).mkdirs()
File(base + "dialogs").mkdirs() File(base + "dialogs").mkdirs()
logger.debug("Fetching dialogs") logger.debug("Fetching dialogs")
val dialogs = db.getListOfDialogsForExport() val dialogs = db.getListOfDialogsForExport()
logger.trace("Got {} dialogs", dialogs.size()) logger.trace("Got {} dialogs", dialogs.size)
logger.debug("Fetching chats") logger.debug("Fetching chats")
val chats = db.getListOfChatsForExport() val chats = db.getListOfChatsForExport()
logger.trace("Got {} chats", chats.size()) logger.trace("Got {} chats", chats.size)
logger.debug("Generating index.html") logger.debug("Generating index.html")
val scope = HashMap<String, Object>() val scope = HashMap<String, Any>()
scope.put("user", user) scope.put("user", user)
scope.put("dialogs", dialogs) scope.put("dialogs", dialogs)
scope.put("chats", chats) scope.put("chats", chats)
// Collect stats data // Collect stats data
scope.put("count.chats", chats.size()) scope.put("count.chats", chats.size)
scope.put("count.dialogs", dialogs.size()) scope.put("count.dialogs", dialogs.size)
var count_messages_chats = 0 var count_messages_chats = 0
var count_messages_dialogs = 0 var count_messages_dialogs = 0
@ -97,10 +97,10 @@ class HTMLExporter {
mustache = mf.compile("templates/html/chat.mustache") mustache = mf.compile("templates/html/chat.mustache")
var i = 0 var i = 0
logger.debug("Generating {} dialog pages", dialogs.size()) logger.debug("Generating {} dialog pages", dialogs.size)
for (d in dialogs) { for (d in dialogs) {
i++ i++
logger.trace("Dialog {}/{}: {}", i, dialogs.size(), Utils.anonymize("" + d.id)) logger.trace("Dialog {}/{}: {}", i, dialogs.size, Utils.anonymize("" + d.id))
val messages = db.getMessagesForExport(d) val messages = db.getMessagesForExport(d)
scope.clear() scope.clear()
scope.put("user", user) scope.put("user", user)
@ -118,10 +118,10 @@ class HTMLExporter {
} }
i = 0 i = 0
logger.debug("Generating {} chat pages", chats.size()) logger.debug("Generating {} chat pages", chats.size)
for (c in chats) { for (c in chats) {
i++ i++
logger.trace("Chat {}/{}: {}", i, chats.size(), Utils.anonymize("" + c.id)) logger.trace("Chat {}/{}: {}", i, chats.size, Utils.anonymize("" + c.id))
val messages = db.getMessagesForExport(c) val messages = db.getMessagesForExport(c)
scope.clear() scope.clear()
scope.put("user", user) scope.put("user", user)
@ -140,7 +140,7 @@ class HTMLExporter {
logger.debug("Generating additional files") logger.debug("Generating additional files")
// Copy CSS // Copy CSS
val cssFile = getClass().getResource("/templates/html/style.css") val cssFile = javaClass.getResource("/templates/html/style.css")
val dest = File(base + "style.css") val dest = File(base + "style.css")
FileUtils.copyURLToFile(cssFile, dest) FileUtils.copyURLToFile(cssFile, dest)
logger.debug("Done exporting.") logger.debug("Done exporting.")
@ -173,8 +173,8 @@ class HTMLExporter {
private fun mapToString(map: Map<String, Integer>): String { private fun mapToString(map: Map<String, Integer>): String {
val sb = StringBuilder("[") val sb = StringBuilder("[")
for (entry in map.entrySet()) { for ((key, value) in map) {
sb.append("['" + entry.getKey() + "', " + entry.getValue() + "],") sb.append("['$key', $value],")
} }
sb.append("]") sb.append("]")
return sb.toString() return sb.toString()

View File

@ -44,33 +44,34 @@ import java.util.concurrent.TimeoutException
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
abstract class AbstractMediaFileManager(protected var message: TLMessage, protected var user: UserManager, protected var client: TelegramClient) { abstract class AbstractMediaFileManager(protected var message: TLMessage, protected var user: UserManager, protected var client: TelegramClient) {
var isEmpty = false open var isEmpty = false
abstract val size: Int abstract val size: Int
abstract val extension: String abstract val extension: String
val downloaded: Boolean open val downloaded: Boolean
get() = File(targetPathAndFilename).isFile() get() = File(targetPathAndFilename).isFile()
val downloading: Boolean val downloading: Boolean
get() = File("${targetPathAndFilename}.downloading").isFile() get() = File("${targetPathAndFilename}.downloading").isFile()
val targetPath: String open val targetPath: String
get() { get() {
val path = user.getFileBase() + Config.FILE_FILES_BASE + File.separatorChar val path = user.fileBase + Config.FILE_FILES_BASE + File.separatorChar
File(path).mkdirs() File(path).mkdirs()
return path return path
} }
val targetFilename: String open val targetFilename: String
get() { get() {
val message_id = message.getId() val message_id = message.getId()
if (message.getToId() is TLPeerChannel) { var to = message.getToId()
val channel_id = message.getToId().getChannelId() if (to is TLPeerChannel) {
val channel_id = to.getChannelId()
return "channel_${channel_id}_${message_id}.$extension" return "channel_${channel_id}_${message_id}.$extension"
} else return "${message_id}.$extension" } else return "${message_id}.$extension"
} }
val targetPathAndFilenam: String open val targetPathAndFilename: String
get() = targetPath + targetFilename get() = targetPath + targetFilename
abstract val letter: String abstract val letter: String
@ -91,7 +92,9 @@ abstract class AbstractMediaFileManager(protected var message: TLMessage, protec
} }
fun throwUnexpectedObjectError(o: Object) { companion object {
throw RuntimeException("Unexpected " + o.getClass().getName()) fun throwUnexpectedObjectError(o: Any) {
throw RuntimeException("Unexpected " + o.javaClass.getName())
}
} }
} }

View File

@ -42,26 +42,23 @@ import java.util.concurrent.TimeoutException
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
class DocumentFileManager(msg: TLMessage, user: UserManager, client: TelegramClient) : AbstractMediaFileManager(msg, user, client) { open class DocumentFileManager(msg: TLMessage, user: UserManager, client: TelegramClient) : AbstractMediaFileManager(msg, user, client) {
protected var doc: TLDocument? = null protected var doc: TLDocument? = null
private var extension: String? = null override lateinit var extension: String
val isSticker: Boolean open val isSticker: Boolean
get() { get() {
var sticker: TLDocumentAttributeSticker? = null var sticker: TLDocumentAttributeSticker? = null
if (this.isEmpty || doc == null) return false if (this.isEmpty || doc == null) return false
return doc!!.getAttributes()?.filter{it is TLDocumentAttributeSticker}.isNotEmpty() return doc!!.getAttributes()?.filter{it is TLDocumentAttributeSticker}?.isNotEmpty() ?: false
} }
val size: Int override val size: Int
get() = if (doc != null) doc!!.getSize() else 0 get() = if (doc != null) doc!!.getSize() else 0
val letter: String open override val letter: String = "d"
get() = "d" open override val name: String = "document"
val name: String open override val description: String = "Document"
get() = "document"
val description: String
get() = "Document"
init { init {
val d = (msg.getMedia() as TLMessageMediaDocument).getDocument() val d = (msg.getMedia() as TLMessageMediaDocument).getDocument()
@ -72,9 +69,10 @@ class DocumentFileManager(msg: TLMessage, user: UserManager, client: TelegramCli
} else { } else {
throwUnexpectedObjectError(d) throwUnexpectedObjectError(d)
} }
extension = processExtension()
} }
fun getExtension(): String? { private fun processExtension(): String {
if (extension != null) return extension if (extension != null) return extension
if (doc == null) return "empty" if (doc == null) return "empty"
var ext: String? = null var ext: String? = null
@ -97,14 +95,13 @@ class DocumentFileManager(msg: TLMessage, user: UserManager, client: TelegramCli
// Sometimes, extensions contain a trailing double quote. Remove this. Fixes #12. // Sometimes, extensions contain a trailing double quote. Remove this. Fixes #12.
ext = ext!!.replace("\"", "") ext = ext!!.replace("\"", "")
this.extension = ext
return ext return ext
} }
@Throws(RpcErrorException::class, IOException::class, TimeoutException::class) @Throws(RpcErrorException::class, IOException::class, TimeoutException::class)
fun download() { override fun download() {
if (doc != null) { if (doc != null) {
DownloadManager.downloadFile(client, getTargetPathAndFilename(), size, doc!!.getDcId(), doc!!.getId(), doc!!.getAccessHash()) DownloadManager.downloadFile(client, targetPathAndFilename, size, doc!!.getDcId(), doc!!.getId(), doc!!.getAccessHash())
} }
} }
} }

View File

@ -50,7 +50,7 @@ object FileManagerFactory {
return PhotoFileManager(m, u, c) return PhotoFileManager(m, u, c)
} else if (media is TLMessageMediaDocument) { } else if (media is TLMessageMediaDocument) {
val d = DocumentFileManager(m, u, c) val d = DocumentFileManager(m, u, c)
return if (d.isSticker()) { return if (d.isSticker) {
StickerFileManager(m, u, c) StickerFileManager(m, u, c)
} else d } else d
} else if (media is TLMessageMediaGeo) { } else if (media is TLMessageMediaGeo) {

View File

@ -44,24 +44,21 @@ import java.util.concurrent.TimeoutException
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
class GeoFileManager(msg: TLMessage, user: UserManager, client: TelegramClient) : AbstractMediaFileManager(msg, user, client) { class GeoFileManager(msg: TLMessage, user: UserManager, client: TelegramClient) : AbstractMediaFileManager(msg, user, client) {
protected var geo: TLGeoPoint protected lateinit var geo: TLGeoPoint
// We don't know the size, so we just guess. // We don't know the size, so we just guess.
val size: Int override val size: Int
get() { get() {
val f = File(getTargetPathAndFilename()) val f = File(targetPathAndFilename)
return if (f.isFile()) f.length() else 100000 return if (f.isFile()) (f.length() as Int) else 100000
} }
val extension: String override val extension: String
get() = "png" get() = "png"
val letter: String override val letter = "g"
get() = "g" override val name = "geo"
val name: String override val description = "Geolocation"
get() = "geo"
val description: String
get() = "Geolocation"
init { init {
val g = (msg.getMedia() as TLMessageMediaGeo).getGeo() val g = (msg.getMedia() as TLMessageMediaGeo).getGeo()
@ -75,11 +72,11 @@ class GeoFileManager(msg: TLMessage, user: UserManager, client: TelegramClient)
} }
@Throws(IOException::class) @Throws(IOException::class)
fun download() { override fun download() {
val url = "https://maps.googleapis.com/maps/api/staticmap?" + val url = "https://maps.googleapis.com/maps/api/staticmap?" +
"center=" + geo.getLat() + "," + geo.getLong() + "&" + "center=" + geo.getLat() + "," + geo.getLong() + "&" +
"zoom=14&size=300x150&scale=2&format=png&" + "zoom=14&size=300x150&scale=2&format=png&" +
"key=" + Config.SECRET_GMAPS "key=" + Config.SECRET_GMAPS
DownloadManager.downloadExternalFile(getTargetPathAndFilename(), url) DownloadManager.downloadExternalFile(targetPathAndFilename, url)
} }
} }

View File

@ -43,18 +43,14 @@ import java.util.concurrent.TimeoutException
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
class PhotoFileManager(msg: TLMessage, user: UserManager, client: TelegramClient) : AbstractMediaFileManager(msg, user, client) { class PhotoFileManager(msg: TLMessage, user: UserManager, client: TelegramClient) : AbstractMediaFileManager(msg, user, client) {
private var photo: TLPhoto? = null private lateinit var photo: TLPhoto
private var size: TLPhotoSize? = null override var size = 0
private lateinit var photo_size: TLPhotoSize
val extension: String override val extension = "jpg"
get() = "jpg" override val letter = "p"
override val name = "photo"
val letter: String override val description = "Photo"
get() = "p"
val name: String
get() = "photo"
val description: String
get() = "Photo"
init { init {
val p = (msg.getMedia() as TLMessageMediaPhoto).getPhoto() val p = (msg.getMedia() as TLMessageMediaPhoto).getPhoto()
@ -72,7 +68,8 @@ class PhotoFileManager(msg: TLMessage, user: UserManager, client: TelegramClient
if (biggest == null) { if (biggest == null) {
throw RuntimeException("Could not find a size for a photo.") throw RuntimeException("Could not find a size for a photo.")
} }
this.size = biggest this.photo_size = biggest
this.size = biggest.getSize()
} else if (p is TLPhotoEmpty) { } else if (p is TLPhotoEmpty) {
this.isEmpty = true this.isEmpty = true
} else { } else {
@ -80,14 +77,10 @@ class PhotoFileManager(msg: TLMessage, user: UserManager, client: TelegramClient
} }
} }
fun getSize(): Int {
return if (size != null) size!!.getSize() else 0
}
@Throws(RpcErrorException::class, IOException::class, TimeoutException::class) @Throws(RpcErrorException::class, IOException::class, TimeoutException::class)
fun download() { override fun download() {
if (isEmpty) return if (isEmpty) return
val loc = size!!.getLocation() as TLFileLocation val loc = photo_size.getLocation() as TLFileLocation
DownloadManager.downloadFile(client, getTargetPathAndFilename(), getSize(), loc.getDcId(), loc.getVolumeId(), loc.getLocalId(), loc.getSecret()) DownloadManager.downloadFile(client, targetPathAndFilename, size, loc.getDcId(), loc.getVolumeId(), loc.getLocalId(), loc.getSecret())
} }
} }

View File

@ -52,13 +52,12 @@ import org.apache.commons.io.FileUtils
class StickerFileManager(msg: TLMessage, user: UserManager, client: TelegramClient) : DocumentFileManager(msg, user, client) { class StickerFileManager(msg: TLMessage, user: UserManager, client: TelegramClient) : DocumentFileManager(msg, user, client) {
val isSticker: Boolean override val isSticker = true
get() = true
private val filenameBase: String private val filenameBase: String
get() { get() {
var sticker: TLDocumentAttributeSticker? = null var sticker: TLDocumentAttributeSticker? = null
for (attr in doc.getAttributes()) { for (attr in doc!!.getAttributes()) {
if (attr is TLDocumentAttributeSticker) { if (attr is TLDocumentAttributeSticker) {
sticker = attr as TLDocumentAttributeSticker sticker = attr as TLDocumentAttributeSticker
} }
@ -75,34 +74,33 @@ class StickerFileManager(msg: TLMessage, user: UserManager, client: TelegramClie
return file.toString() return file.toString()
} }
val targetFilename: String override val targetFilename: String
get() = filenameBase + "." + extension get() = filenameBase + "." + extension
val targetPath: String override val targetPath: String
get() { get() {
val path = user.getFileBase() + Config.FILE_FILES_BASE + File.separatorChar + Config.FILE_STICKER_BASE + File.separatorChar val path = user.fileBase + Config.FILE_FILES_BASE + File.separatorChar + Config.FILE_STICKER_BASE + File.separatorChar
File(path).mkdirs() File(path).mkdirs()
return path return path
} }
val extension: String override var extension = "webp"
get() = "webp"
val letter: String override val letter: String
get() = "s" get() = "s"
val name: String override val name: String
get() = "sticker" get() = "sticker"
val description: String override val description: String
get() = "Sticker" get() = "Sticker"
@Throws(RpcErrorException::class, IOException::class, TimeoutException::class) @Throws(RpcErrorException::class, IOException::class, TimeoutException::class)
fun download() { override fun download() {
val old_file = Config.FILE_BASE + File.separatorChar + Config.FILE_STICKER_BASE + File.separatorChar + targetFilename val old_file = Config.FILE_BASE + File.separatorChar + Config.FILE_STICKER_BASE + File.separatorChar + targetFilename
logger.trace("Old filename exists: {}", File(old_file).exists()) logger.trace("Old filename exists: {}", File(old_file).exists())
if (File(old_file).exists()) { if (File(old_file).exists()) {
Files.copy(Paths.get(old_file), Paths.get(getTargetPathAndFilename()), StandardCopyOption.REPLACE_EXISTING) Files.copy(Paths.get(old_file), Paths.get(targetPathAndFilename), StandardCopyOption.REPLACE_EXISTING)
return return
} }
super.download() super.download()

View File

@ -44,34 +44,15 @@ import java.util.concurrent.TimeoutException
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
class UnsupportedFileManager(msg: TLMessage, user: UserManager, client: TelegramClient, type: String) : AbstractMediaFileManager(msg, user, client) { class UnsupportedFileManager(msg: TLMessage, user: UserManager, client: TelegramClient, type: String) : AbstractMediaFileManager(msg, user, client) {
var name: String? = null override var name = type
internal set override val targetFilename = ""
override val targetPath = ""
override val extension = ""
override val size = 0
override var isEmpty = false
override val downloaded = false
override val letter = " "
override val description = "Unsupported / non-downloadable Media"
val targetFilename: String override fun download() {}
get() = ""
val targetPath: String
get() = ""
val extension: String
get() = ""
val size: Int
get() = 0
val isEmpty: Boolean
get() = false
val isDownloaded: Boolean
get() = false
val letter: String
get() = " "
val description: String
get() = "Unsupported / non-downloadable Media"
init {
this.name = type
}
fun download() {}
} }