1
0
mirror of https://github.com/fabianonline/telegram_backup.git synced 2024-12-25 22:35:35 +00:00

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

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

View File

@ -27,7 +27,7 @@ import java.io.File
import java.io.FileNotFoundException
import java.io.IOException
internal class ApiStorage(prefix: String) : TelegramApiStorage {
internal class ApiStorage(prefix: String?) : TelegramApiStorage {
private var prefix: String? = null
private var do_save = false
private var auth_key: AuthKey? = null
@ -39,7 +39,7 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
this.setPrefix(prefix)
}
fun setPrefix(prefix: String) {
fun setPrefix(prefix: String?) {
this.prefix = prefix
this.do_save = this.prefix != null
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._saveAuthKey()
}
@ -65,7 +65,7 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
private fun _saveAuthKey() {
if (this.do_save && this.auth_key != null) {
try {
FileUtils.writeByteArrayToFile(this.file_auth_key, this.auth_key!!.getKey())
FileUtils.writeByteArrayToFile(this.file_auth_key, this.auth_key!!.key)
} catch (e: IOException) {
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.file_auth_key != null) {
try {
@ -87,7 +87,7 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
return null
}
fun saveDc(dc: DataCenter) {
override fun saveDc(dc: DataCenter) {
this.dc = dc
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.file_dc != null) {
try {
@ -117,7 +117,7 @@ internal class ApiStorage(prefix: String) : TelegramApiStorage {
return null
}
fun deleteAuthKey() {
override fun deleteAuthKey() {
if (this.do_save) {
try {
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) {
try {
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
}
}

View File

@ -30,29 +30,24 @@ import org.slf4j.Logger
class CommandLineController {
private val storage:ApiStorage
var app:TelegramApp
private val line:String
get() {
if (System.console() != null)
{
private fun getLine():String {
if (System.console() != null) {
return System.console().readLine("> ")
}
else
{
} else {
print("> ")
return Scanner(System.`in`).nextLine()
}
}
private val password:String
get() {
if (System.console() != null)
{
private fun getPassword():String {
if (System.console() != null) {
return String(System.console().readPassword("> "))
}
else
{
return line
} else {
return getLine()
}
}
init{
logger.info("CommandLineController started. App version {}", Config.APP_APPVER)
this.printHeader()
@ -67,7 +62,7 @@ class CommandLineController {
}
else if (CommandLineOptions.cmd_license)
{
this.show_license()
CommandLineController.show_license()
System.exit(0)
}
this.setupFileBase()
@ -92,16 +87,16 @@ class CommandLineController {
logger.info("Initializing UserManager")
UserManager.init(client)
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.")
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")
}
}
@ -137,7 +132,7 @@ class CommandLineController {
logger.debug("CommandLineOptions.val_export: {}", CommandLineOptions.val_export)
if (CommandLineOptions.val_export != null)
{
if (CommandLineOptions.val_export.toLowerCase().equals("html"))
if (CommandLineOptions.val_export!!.toLowerCase().equals("html"))
{
(HTMLExporter()).export()
System.exit(0)
@ -147,9 +142,9 @@ class CommandLineController {
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
{
@ -202,13 +197,13 @@ class CommandLineController {
logger.debug("Target dir at startup: {}", Utils.anonymize(Config.FILE_BASE))
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))
System.out.println("Base directory for files: " + Utils.anonymize(Config.FILE_BASE))
}
private fun selectAccount():String {
val account:String = null
private fun selectAccount():String? {
var account = "none"
val accounts = Utils.getAccounts()
if (CommandLineOptions.cmd_login)
{
@ -217,9 +212,9 @@ class CommandLineController {
}
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.")
val found = false
var found = false
for (acc in accounts)
{
logger.trace("Checking {}", Utils.anonymize(acc))
@ -232,16 +227,17 @@ class CommandLineController {
}
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...")
CommandLineOptions.cmd_login = true
return null
}
else if (accounts.size() == 1)
else if (accounts.size == 1)
{
account = accounts.firstElement()
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" +
"Use '--account <x>' to use account <x>.\n" +
"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))
return account
}
@ -260,45 +257,48 @@ class CommandLineController {
println()
println("Stats:")
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 chats", Database.getInstance().getChatCount())
System.out.format(format, "Number of users", Database.getInstance().getUserCount())
System.out.format(format, "Top message ID", Database.getInstance().getTopMessageID())
println()
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("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)
private fun cmd_login(phone:String) {
private fun cmd_login(phoneToUse:String?) {
val user = UserManager.getInstance()
if (phone == null)
val phone: String
if (phoneToUse == null)
{
println("Please enter your phone number in international format.")
println("Example: +4917077651234")
phone = line
}
phone = getLine()
} else {
phone = phoneToUse
}
user.sendCodeToPhoneNumber(phone)
println("Telegram sent you a code. Please enter it here.")
val code = line
val code = getLine()
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.")
val pw = password
val pw = getPassword()
user.verifyPassword(pw)
}
storage.setPrefix("+" + user.getUser().getPhone())
System.out.println("Everything seems fine. Please run this tool again with '--account +" + Utils.anonymize(user.getUser().getPhone()) + " to use this account.")
storage.setPrefix("+" + user.user!!.getPhone())
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() {
println("Valid options are:")
@ -340,14 +340,14 @@ class CommandLineController {
}
companion object {
private val logger = LoggerFactory.getLogger(CommandLineController::class.java)
fun show_error(error:String) {
logger.error(error)
println("ERROR: " + error)
System.exit(1)
}
fun show_license() {
println("TODO: Print the GPL.")
}
public fun show_error(error:String) {
logger.error(error)
println("ERROR: " + error)
System.exit(1)
}
fun show_license() {
println("TODO: Print the GPL.")
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,7 @@ import de.fabianonline.telegram_backup.mediafilemanager.AbstractMediaFileManager
class DatabaseUpdates(protected var conn: Connection, protected var db: Database) {
private val maxPossibleVersion: Int
get() = updates.size()
get() = updates.size
init {
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)
var backup = false
for (i in version + 1..maxPossibleVersion) {
if (getUpdateToVersion(i).needsBackup()) {
if (getUpdateToVersion(i).needsBackup) {
logger.debug("Update to version {} needs a backup", i)
backup = true
}
@ -100,9 +100,9 @@ class DatabaseUpdates(protected var conn: Connection, protected var db: Database
}
private fun register(d: DatabaseUpdate) {
logger.debug("Registering {} as update to version {}", d.getClass().getName(), d.version)
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))
logger.debug("Registering {} as update to version {}", d.javaClass, d.version)
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}")
}
updates.add(d)
}
@ -138,9 +138,7 @@ internal abstract class DatabaseUpdate(protected var conn: Connection, protected
@Throws(SQLException::class)
protected abstract fun _doUpdate()
fun needsBackup(): Boolean {
return false
}
open val needsBackup = false
@Throws(SQLException::class)
protected fun execute(sql: String) {
@ -233,9 +231,7 @@ internal class DB_Update_6(conn: Connection, db: Database) : DatabaseUpdate(conn
override val version: Int
get() = 6
override fun needsBackup(): Boolean {
return true
}
override val needsBackup = true
@Throws(SQLException::class)
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(")
var first: Boolean
first = true
for (s in mappings.keySet()) {
for (s in mappings.keys) {
if (!first) query.append(", ")
query.append(s)
first = false
}
query.append(")\nSELECT \n")
first = true
for (s in mappings.values()) {
for (s in mappings.values) {
if (!first) query.append(", ")
query.append(s)
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=?")
while (rs.next()) {
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) {
ps.setNull(1, Types.INTEGER)
} else {
@ -301,9 +297,9 @@ internal class DB_Update_6(conn: Connection, db: Database) : DatabaseUpdate(conn
ps.setNull(3, Types.VARCHAR)
ps.setNull(4, Types.INTEGER)
} else {
ps.setString(2, f!!.getName())
ps.setString(3, f!!.getTargetFilename())
ps.setInt(4, f!!.getSize())
ps.setString(2, f.name)
ps.setString(3, f.targetFilename)
ps.setInt(4, f.size)
}
ps.addBatch()
}
@ -321,9 +317,7 @@ internal class DB_Update_7(conn: Connection, db: Database) : DatabaseUpdate(conn
override val version: Int
get() = 7
override fun needsBackup(): Boolean {
return true
}
override val needsBackup = true
@Throws(SQLException::class)
override fun _doUpdate() {
@ -337,9 +331,7 @@ internal class DB_Update_8(conn: Connection, db: Database) : DatabaseUpdate(conn
override val version: Int
get() = 8
override fun needsBackup(): Boolean {
return true
}
override val needsBackup = true
@Throws(SQLException::class)
override fun _doUpdate() {

View File

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

View File

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

View File

@ -24,7 +24,7 @@ import java.awt.event.ActionEvent
import java.awt.event.ActionListener
import java.util.Vector
class GUIController {
class GUIController() {
init {
showAccountChooserDialog()
}
@ -50,24 +50,8 @@ class GUIController {
accountChooser.add(vert)
accountChooser.setVisible(true)
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() {
val loginDialog = JDialog()
loginDialog.setTitle("Add an account")

View File

@ -28,16 +28,15 @@ import com.github.badoualy.telegram.tl.StreamUtils.readTLObject
class TLRequestAccountGetPasswordWithCurrentSalt : TLMethod<TLPassword>() {
private val _constructor = "account.getPassword#548a30f5"
val constructorId: Int
get() = CONSTRUCTOR_ID
override fun getConstructorId(): Int = CONSTRUCTOR_ID
@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()")
return response as TLPassword
}
fun toString(): String {
override fun toString(): String {
return _constructor
}

View File

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

View File

@ -39,13 +39,13 @@ private constructor(c: TelegramClient) {
var user: TLUser? = null
var phone: String? = null
private var code: String? = null
private val client: TelegramClient? = null
private val client: TelegramClient
private var sent_code: TLSentCode? = null
private var auth: TLAuthorization? = null
var isPasswordNeeded = false
private set
val isLoggedIn: Boolean
val loggedIn: Boolean
get() = user != null
val userString: String
@ -86,7 +86,7 @@ private constructor(c: TelegramClient) {
@Throws(RpcErrorException::class, IOException::class)
fun sendCodeToPhoneNumber(number: String) {
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)
@ -104,7 +104,7 @@ private constructor(c: TelegramClient) {
@Throws(RpcErrorException::class, IOException::class)
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()
var md: MessageDigest? = null
try {
@ -125,7 +125,7 @@ private constructor(c: TelegramClient) {
companion object {
private val logger = LoggerFactory.getLogger(UserManager::class.java)
private var instance: UserManager? = null
internal var instance: UserManager? = null
@Throws(IOException::class)
fun init(c: TelegramClient) {
@ -134,7 +134,7 @@ private constructor(c: TelegramClient) {
fun getInstance(): UserManager {
if (instance == null) throw RuntimeException("UserManager is not yet initialized.")
return instance
return instance!!
}
}
}

View File

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

View File

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

View File

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

View File

@ -42,26 +42,23 @@ import java.util.concurrent.TimeoutException
import org.apache.commons.io.FileUtils
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
private var extension: String? = null
override lateinit var extension: String
val isSticker: Boolean
open val isSticker: Boolean
get() {
var sticker: TLDocumentAttributeSticker? = null
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
val letter: String
get() = "d"
val name: String
get() = "document"
val description: String
get() = "Document"
open override val letter: String = "d"
open override val name: String = "document"
open override val description: String = "Document"
init {
val d = (msg.getMedia() as TLMessageMediaDocument).getDocument()
@ -72,9 +69,10 @@ class DocumentFileManager(msg: TLMessage, user: UserManager, client: TelegramCli
} else {
throwUnexpectedObjectError(d)
}
extension = processExtension()
}
fun getExtension(): String? {
private fun processExtension(): String {
if (extension != null) return extension
if (doc == null) return "empty"
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.
ext = ext!!.replace("\"", "")
this.extension = ext
return ext
}
@Throws(RpcErrorException::class, IOException::class, TimeoutException::class)
fun download() {
override fun download() {
if (doc != null) {
DownloadManager.downloadFile(client, getTargetPathAndFilename(), size, doc!!.getDcId(), doc!!.getId(), doc!!.getAccessHash())
DownloadManager.downloadFile(client, targetPathAndFilename, size, doc!!.getDcId(), doc!!.getId(), doc!!.getAccessHash())
}
}
}

View File

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

View File

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

View File

@ -43,18 +43,14 @@ import java.util.concurrent.TimeoutException
import org.apache.commons.io.FileUtils
class PhotoFileManager(msg: TLMessage, user: UserManager, client: TelegramClient) : AbstractMediaFileManager(msg, user, client) {
private var photo: TLPhoto? = null
private var size: TLPhotoSize? = null
private lateinit var photo: TLPhoto
override var size = 0
private lateinit var photo_size: TLPhotoSize
val extension: String
get() = "jpg"
val letter: String
get() = "p"
val name: String
get() = "photo"
val description: String
get() = "Photo"
override val extension = "jpg"
override val letter = "p"
override val name = "photo"
override val description = "Photo"
init {
val p = (msg.getMedia() as TLMessageMediaPhoto).getPhoto()
@ -72,7 +68,8 @@ class PhotoFileManager(msg: TLMessage, user: UserManager, client: TelegramClient
if (biggest == null) {
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) {
this.isEmpty = true
} 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)
fun download() {
override fun download() {
if (isEmpty) return
val loc = size!!.getLocation() as TLFileLocation
DownloadManager.downloadFile(client, getTargetPathAndFilename(), getSize(), loc.getDcId(), loc.getVolumeId(), loc.getLocalId(), loc.getSecret())
val loc = photo_size.getLocation() as TLFileLocation
DownloadManager.downloadFile(client, targetPathAndFilename, size, loc.getDcId(), loc.getVolumeId(), loc.getLocalId(), loc.getSecret())
}
}

View File

@ -52,13 +52,12 @@ import org.apache.commons.io.FileUtils
class StickerFileManager(msg: TLMessage, user: UserManager, client: TelegramClient) : DocumentFileManager(msg, user, client) {
val isSticker: Boolean
get() = true
override val isSticker = true
private val filenameBase: String
get() {
var sticker: TLDocumentAttributeSticker? = null
for (attr in doc.getAttributes()) {
for (attr in doc!!.getAttributes()) {
if (attr is TLDocumentAttributeSticker) {
sticker = attr as TLDocumentAttributeSticker
}
@ -75,34 +74,33 @@ class StickerFileManager(msg: TLMessage, user: UserManager, client: TelegramClie
return file.toString()
}
val targetFilename: String
override val targetFilename: String
get() = filenameBase + "." + extension
val targetPath: String
override val targetPath: String
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()
return path
}
val extension: String
get() = "webp"
override var extension = "webp"
val letter: String
override val letter: String
get() = "s"
val name: String
override val name: String
get() = "sticker"
val description: String
override val description: String
get() = "Sticker"
@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
logger.trace("Old filename exists: {}", 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
}
super.download()

View File

@ -44,34 +44,15 @@ import java.util.concurrent.TimeoutException
import org.apache.commons.io.FileUtils
class UnsupportedFileManager(msg: TLMessage, user: UserManager, client: TelegramClient, type: String) : AbstractMediaFileManager(msg, user, client) {
var name: String? = null
internal set
val targetFilename: String
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() {}
override var name = type
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"
override fun download() {}
}