mirror of
https://github.com/fabianonline/telegram_backup.git
synced 2024-11-23 01:06:17 +00:00
Commandline-Stuff, Database-stuff.
This commit is contained in:
parent
1c3d10befb
commit
29d5fc37d0
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ build/
|
|||||||
.gradle/
|
.gradle/
|
||||||
auth.dat
|
auth.dat
|
||||||
dc.dat
|
dc.dat
|
||||||
|
data/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'application'
|
apply plugin: 'application'
|
||||||
|
|
||||||
mainClassName= 'de.fabianonline.telegram_backup.Main'
|
mainClassName= 'de.fabianonline.telegram_backup.CommandLineRunner'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@ -12,6 +12,7 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'com.github.badoualy:kotlogram:0.0.6'
|
compile 'com.github.badoualy:kotlogram:0.0.6'
|
||||||
|
compile 'org.xerial:sqlite-jdbc:3.8.11.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
run {
|
run {
|
||||||
|
@ -11,57 +11,110 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
class ApiStorage implements TelegramApiStorage {
|
class ApiStorage implements TelegramApiStorage {
|
||||||
|
private String prefix = null;
|
||||||
|
private boolean do_save = false;
|
||||||
|
private AuthKey auth_key = null;
|
||||||
|
private DataCenter dc = null;
|
||||||
|
private File file_auth_key = null;
|
||||||
|
private File file_dc = null;
|
||||||
|
|
||||||
|
public ApiStorage(String prefix) {
|
||||||
|
this.setPrefix(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrefix(String prefix) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.do_save = (this.prefix!=null);
|
||||||
|
if (this.do_save) {
|
||||||
|
String base = Config.FILE_BASE +
|
||||||
|
File.separatorChar +
|
||||||
|
this.prefix +
|
||||||
|
File.separatorChar;
|
||||||
|
this.file_auth_key = new File(base + Config.FILE_NAME_AUTH_KEY);
|
||||||
|
this.file_dc = new File(base + Config.FILE_NAME_DC);
|
||||||
|
this._saveAuthKey();
|
||||||
|
this._saveDc();
|
||||||
|
} else {
|
||||||
|
this.file_auth_key = null;
|
||||||
|
this.file_dc = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void saveAuthKey(AuthKey authKey) {
|
public void saveAuthKey(AuthKey authKey) {
|
||||||
|
this.auth_key = authKey;
|
||||||
|
this._saveAuthKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _saveAuthKey() {
|
||||||
|
if (this.do_save && this.auth_key!=null) {
|
||||||
try {
|
try {
|
||||||
FileUtils.writeByteArrayToFile(Config.FILE_AUTH_KEY, authKey.getKey());
|
FileUtils.writeByteArrayToFile(this.file_auth_key, this.auth_key.getKey());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public AuthKey loadAuthKey() {
|
public AuthKey loadAuthKey() {
|
||||||
|
if (this.auth_key != null) return this.auth_key;
|
||||||
|
if (this.file_auth_key != null) {
|
||||||
try {
|
try {
|
||||||
return new AuthKey(FileUtils.readFileToByteArray(Config.FILE_AUTH_KEY));
|
return new AuthKey(FileUtils.readFileToByteArray(this.file_auth_key));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (!(e instanceof FileNotFoundException)) e.printStackTrace();
|
if (!(e instanceof FileNotFoundException)) e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveDc(DataCenter dc) {
|
public void saveDc(DataCenter dc) {
|
||||||
|
this.dc = dc;
|
||||||
|
this._saveDc();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _saveDc() {
|
||||||
|
if (this.do_save && this.dc != null) {
|
||||||
try {
|
try {
|
||||||
FileUtils.write(Config.FILE_DC, dc.toString());
|
FileUtils.write(this.file_dc, this.dc.toString());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public DataCenter loadDc() {
|
public DataCenter loadDc() {
|
||||||
|
if (this.dc != null) return this.dc;
|
||||||
|
if (this.file_dc != null) {
|
||||||
try {
|
try {
|
||||||
String[] infos = FileUtils.readFileToString(Config.FILE_DC).split(":");
|
String[] infos = FileUtils.readFileToString(this.file_dc).split(":");
|
||||||
return new DataCenter(infos[0], Integer.parseInt(infos[1]));
|
return new DataCenter(infos[0], Integer.parseInt(infos[1]));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (!(e instanceof FileNotFoundException)) e.printStackTrace();
|
if (!(e instanceof FileNotFoundException)) e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAuthKey() {
|
public void deleteAuthKey() {
|
||||||
|
if (this.do_save) {
|
||||||
try {
|
try {
|
||||||
FileUtils.forceDelete(Config.FILE_AUTH_KEY);
|
FileUtils.forceDelete(this.file_auth_key);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void deleteDc() {
|
public void deleteDc() {
|
||||||
|
if (this.do_save) {
|
||||||
try {
|
try {
|
||||||
FileUtils.forceDelete(Config.FILE_DC);
|
FileUtils.forceDelete(this.file_dc);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void saveServerSalt(long salt) {}
|
public void saveServerSalt(long salt) {}
|
||||||
|
|
||||||
|
@ -0,0 +1,150 @@
|
|||||||
|
package de.fabianonline.telegram_backup;
|
||||||
|
|
||||||
|
import com.github.badoualy.telegram.api.Kotlogram;
|
||||||
|
import com.github.badoualy.telegram.api.TelegramApp;
|
||||||
|
import com.github.badoualy.telegram.api.TelegramClient;
|
||||||
|
import com.github.badoualy.telegram.tl.exception.RpcErrorException;
|
||||||
|
|
||||||
|
import de.fabianonline.telegram_backup.Config;
|
||||||
|
import de.fabianonline.telegram_backup.ApiStorage;
|
||||||
|
import de.fabianonline.telegram_backup.UserManager;
|
||||||
|
import de.fabianonline.telegram_backup.DownloadManager;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class CommandLineController {
|
||||||
|
private ApiStorage storage;
|
||||||
|
private CommandLineOptions options;
|
||||||
|
public TelegramApp app;
|
||||||
|
public UserManager user = null;
|
||||||
|
|
||||||
|
public CommandLineController(String[] args) {
|
||||||
|
options = new CommandLineOptions(args);
|
||||||
|
if (options.cmd_help) this.show_help();
|
||||||
|
if (options.cmd_list_accounts) this.list_accounts();
|
||||||
|
if (options.account==null && !options.cmd_login) {
|
||||||
|
show_error("You neither used --login nor did you give an account using --account. You need to use one of those two.\nPlease have a look at --help.");
|
||||||
|
}
|
||||||
|
|
||||||
|
app = new TelegramApp(Config.APP_ID, Config.APP_HASH, Config.APP_MODEL, Config.APP_SYSVER, Config.APP_APPVER, Config.APP_LANG);
|
||||||
|
if (options.cmd_debug) Kotlogram.setDebugLogEnabled(true);
|
||||||
|
|
||||||
|
if (options.account != null && !options.cmd_login) {
|
||||||
|
storage = new ApiStorage(options.account);
|
||||||
|
} else {
|
||||||
|
storage = new ApiStorage(null);
|
||||||
|
}
|
||||||
|
TelegramClient client = Kotlogram.getDefaultClient(app, storage);
|
||||||
|
|
||||||
|
try {
|
||||||
|
user = new UserManager(client);
|
||||||
|
|
||||||
|
if (options.cmd_login) {
|
||||||
|
System.out.println("Please enter your phone number in international format.");
|
||||||
|
System.out.println("Example: +4917077651234");
|
||||||
|
System.out.print("> ");
|
||||||
|
String phone = new Scanner(System.in).nextLine();
|
||||||
|
user.sendCodeToPhoneNumber(phone);
|
||||||
|
|
||||||
|
System.out.println("Telegram sent you a code. Please enter it here.");
|
||||||
|
System.out.print("> ");
|
||||||
|
String code = new Scanner(System.in).nextLine();
|
||||||
|
user.verifyCode(code);
|
||||||
|
|
||||||
|
if (user.isPasswordNeeded()) {
|
||||||
|
System.out.println("We also need your account password.");
|
||||||
|
System.out.print("> ");
|
||||||
|
String pw = new Scanner(System.in).nextLine();
|
||||||
|
user.verifyPassword(pw);
|
||||||
|
}
|
||||||
|
storage.setPrefix(user.getUser().getPhone());
|
||||||
|
|
||||||
|
System.out.println("Next time, please run this tool with '--account " + user.getUser().getPhone() + " to use this account.");
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("You are now signed in as " + user.getUserString());
|
||||||
|
|
||||||
|
DownloadManager d = new DownloadManager(user);
|
||||||
|
d.downloadMessages();
|
||||||
|
} catch (RpcErrorException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
System.out.println("----- EXIT -----");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void show_help() {
|
||||||
|
System.out.println("Valid options are:");
|
||||||
|
System.out.println(" --help Shows this help.");
|
||||||
|
System.out.println(" --account <x> Use account <x>.");
|
||||||
|
System.out.println(" --login Login to an existing telegram account.");
|
||||||
|
System.out.println(" --debug Show (lots of) debug information.");
|
||||||
|
System.out.println(" --list-accounts List all existing accounts");
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void list_accounts() {
|
||||||
|
System.out.println("List of available accounts:");
|
||||||
|
int count = 0;
|
||||||
|
File folder = new File(Config.FILE_BASE);
|
||||||
|
File[] files = folder.listFiles();
|
||||||
|
for (File f : files) {
|
||||||
|
if (f.isDirectory()) {
|
||||||
|
count++;
|
||||||
|
System.out.println(" " + f.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count>0) {
|
||||||
|
System.out.println("Use '--acount <x>' to use one of those accounts.");
|
||||||
|
} else {
|
||||||
|
System.out.println("NO ACCOUNTS FOUND");
|
||||||
|
System.out.println("Use '--login' to login to a telegram account.");
|
||||||
|
}
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void show_error(String error) {
|
||||||
|
System.out.println("ERROR: " + error);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CommandLineOptions {
|
||||||
|
public String account = null;
|
||||||
|
public boolean cmd_help = false;
|
||||||
|
public boolean cmd_login = false;
|
||||||
|
public boolean cmd_debug = false;
|
||||||
|
public boolean cmd_list_accounts = false;
|
||||||
|
|
||||||
|
public CommandLineOptions(String[] args) {
|
||||||
|
String last_cmd = null;
|
||||||
|
|
||||||
|
for (String arg : args) {
|
||||||
|
if (last_cmd != null) {
|
||||||
|
switch(last_cmd) {
|
||||||
|
case "--account": this.account=arg; break;
|
||||||
|
}
|
||||||
|
last_cmd = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(arg) {
|
||||||
|
case "--account": last_cmd=arg; continue;
|
||||||
|
case "--help": this.cmd_help=true; break;
|
||||||
|
case "--login": this.cmd_login=true; break;
|
||||||
|
case "--debug": this.cmd_debug=true; break;
|
||||||
|
case "--list-accounts": this.cmd_list_accounts=true; break;
|
||||||
|
default: throw new RuntimeException("Unknown command " + arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (last_cmd != null) {
|
||||||
|
CommandLineController.show_error("Command " + last_cmd + " had no parameter set.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package de.fabianonline.telegram_backup;
|
||||||
|
|
||||||
|
import de.fabianonline.telegram_backup.CommandLineController;
|
||||||
|
|
||||||
|
public class CommandLineRunner {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new CommandLineController(args);
|
||||||
|
}
|
||||||
|
}
|
@ -10,8 +10,9 @@ class Config {
|
|||||||
public static final String APP_APPVER = "0.1";
|
public static final String APP_APPVER = "0.1";
|
||||||
public static final String APP_LANG = "en";
|
public static final String APP_LANG = "en";
|
||||||
|
|
||||||
public static final File FILE_AUTH_KEY = new File("auth.dat");
|
public static final String FILE_BASE = "data";
|
||||||
public static final File FILE_DC = new File("dc.dat");
|
public static final String FILE_NAME_AUTH_KEY = "auth.dat";
|
||||||
public static final File FILE_SALT = new File("salt.dat");
|
public static final String FILE_NAME_DC = "dc.dat";
|
||||||
|
public static final String FILE_NAME_DB = "database.sqlite";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
97
src/main/java/de/fabianonline/telegram_backup/Database.java
Normal file
97
src/main/java/de/fabianonline/telegram_backup/Database.java
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package de.fabianonline.telegram_backup;
|
||||||
|
|
||||||
|
import com.github.badoualy.telegram.tl.api.TLMessage;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import de.fabianonline.telegram_backup.UserManager;
|
||||||
|
|
||||||
|
|
||||||
|
class Database {
|
||||||
|
private Connection conn;
|
||||||
|
private Statement stmt;
|
||||||
|
|
||||||
|
public Database(UserManager user) {
|
||||||
|
try {
|
||||||
|
Class.forName("org.sqlite.JDBC");
|
||||||
|
} catch(ClassNotFoundException e) {
|
||||||
|
CommandLineController.show_error("Could not load jdbc-sqlite class.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String path = "jdbc:sqlite:" +
|
||||||
|
Config.FILE_BASE +
|
||||||
|
File.separatorChar +
|
||||||
|
user.getUser().getPhone() +
|
||||||
|
File.separatorChar +
|
||||||
|
Config.FILE_NAME_DB;
|
||||||
|
|
||||||
|
try {
|
||||||
|
conn = DriverManager.getConnection(path);
|
||||||
|
stmt = conn.createStatement();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
CommandLineController.show_error("Could not connect to SQLITE database.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
try {
|
||||||
|
int version;
|
||||||
|
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='database_versions'");
|
||||||
|
rs.next();
|
||||||
|
if (rs.getInt(1)==0) {
|
||||||
|
version = 0;
|
||||||
|
} else {
|
||||||
|
rs.close();
|
||||||
|
rs = stmt.executeQuery("SELECT MAX(version) FROM database_versions");
|
||||||
|
rs.next();
|
||||||
|
version = rs.getInt(1);
|
||||||
|
rs.close();
|
||||||
|
}
|
||||||
|
System.out.println("Database version: " + version);
|
||||||
|
|
||||||
|
if (version==0) {
|
||||||
|
stmt.executeUpdate("CREATE TABLE messages ("
|
||||||
|
+ "id INTEGER PRIMARY KEY ASC, "
|
||||||
|
+ "dialog_id INTEGER, "
|
||||||
|
+ "to_id INTEGER, "
|
||||||
|
+ "from_id INTEGER, "
|
||||||
|
+ "type TEXT, "
|
||||||
|
+ "text TEXT, "
|
||||||
|
+ "time TEXT, "
|
||||||
|
+ "has_media BOOLEAN, "
|
||||||
|
+ "data BLOB)");
|
||||||
|
stmt.executeUpdate("CREATE TABLE dialogs ("
|
||||||
|
+ "id INTEGER PRIMARY KEY ASC, "
|
||||||
|
+ "name TEXT, "
|
||||||
|
+ "type TEXT)");
|
||||||
|
stmt.executeUpdate("CREATE TABLE people ("
|
||||||
|
+ "id INTEGER PRIMARY KEY ASC, "
|
||||||
|
+ "name TEXT, "
|
||||||
|
+ "username TEXT, "
|
||||||
|
+ "type TEXT)");
|
||||||
|
stmt.executeUpdate("CREATE TABLE database_versions ("
|
||||||
|
+ "version INTEGER)");
|
||||||
|
stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (1)");
|
||||||
|
version = 1;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getSQLState());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(TLMessage msg) {
|
||||||
|
/*BufferArrayOutputStream stream = new BufferArrayOutputStream();
|
||||||
|
msg.serializeBody(stream);
|
||||||
|
bytes[] = stream.toByteArray();
|
||||||
|
PreparedStatement ps = conn.prepareStatement(query);
|
||||||
|
ps.setBytes(x, bytes[]);*/
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package de.fabianonline.telegram_backup;
|
||||||
|
|
||||||
|
import de.fabianonline.telegram_backup.UserManager;
|
||||||
|
import de.fabianonline.telegram_backup.Database;
|
||||||
|
|
||||||
|
class DownloadManager {
|
||||||
|
UserManager user;
|
||||||
|
Database db;
|
||||||
|
|
||||||
|
public DownloadManager(UserManager u) {
|
||||||
|
this.user = u;
|
||||||
|
this.db = new Database(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void downloadMessages() {
|
||||||
|
System.out.println("downloading messages... not.");
|
||||||
|
}
|
||||||
|
}
|
@ -1,60 +0,0 @@
|
|||||||
package de.fabianonline.telegram_backup;
|
|
||||||
|
|
||||||
import com.github.badoualy.telegram.api.Kotlogram;
|
|
||||||
import com.github.badoualy.telegram.api.TelegramApp;
|
|
||||||
import com.github.badoualy.telegram.api.TelegramClient;
|
|
||||||
import com.github.badoualy.telegram.tl.exception.RpcErrorException;
|
|
||||||
|
|
||||||
import de.fabianonline.telegram_backup.Config;
|
|
||||||
import de.fabianonline.telegram_backup.ApiStorage;
|
|
||||||
import de.fabianonline.telegram_backup.UserManager;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Scanner;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
public static TelegramApp app = new TelegramApp(Config.APP_ID, Config.APP_HASH, Config.APP_MODEL, Config.APP_SYSVER, Config.APP_APPVER, Config.APP_LANG);
|
|
||||||
public static UserManager user = null;
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
System.out.println("Hello World");
|
|
||||||
|
|
||||||
Kotlogram.setDebugLogEnabled(true);
|
|
||||||
|
|
||||||
TelegramClient client = Kotlogram.getDefaultClient(app, new ApiStorage());
|
|
||||||
|
|
||||||
try {
|
|
||||||
user = new UserManager(client);
|
|
||||||
|
|
||||||
if (!user.isLoggedIn()) {
|
|
||||||
System.out.println("Please enter your phone number in international format.");
|
|
||||||
System.out.println("Example: +4917077651234");
|
|
||||||
System.out.print("> ");
|
|
||||||
String phone = new Scanner(System.in).nextLine();
|
|
||||||
user.sendCodeToPhoneNumber(phone);
|
|
||||||
|
|
||||||
System.out.println("Telegram sent you a code. Please enter it here.");
|
|
||||||
System.out.print("> ");
|
|
||||||
String code = new Scanner(System.in).nextLine();
|
|
||||||
user.verifyCode(code);
|
|
||||||
|
|
||||||
if (user.isPasswordNeeded()) {
|
|
||||||
System.out.println("We also need your account password.");
|
|
||||||
System.out.print("> ");
|
|
||||||
String pw = new Scanner(System.in).nextLine();
|
|
||||||
user.verifyPassword(pw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("You are now signed in as " + user.getUserString());
|
|
||||||
} catch (RpcErrorException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
System.out.println("----- EXIT -----");
|
|
||||||
}
|
|
||||||
}
|
|
@ -89,4 +89,6 @@ class UserManager {
|
|||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TLUser getUser() { return this.user; }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user