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:
parent
9832d429b0
commit
f75a90936d
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.")
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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? {
|
||||||
|
@ -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() {
|
||||||
|
@ -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.")
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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() {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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() {}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user