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

WIP: Added Daemon-mode to keep the app running and save new messages in real time.

This commit is contained in:
Fabian Schlenz 2016-07-06 18:07:04 +02:00
parent e1cfaf670e
commit 515efb2fde
5 changed files with 192 additions and 33 deletions

View File

@ -16,6 +16,8 @@
package de.fabianonline.telegram_backup; package de.fabianonline.telegram_backup;
import de.fabianonline.telegram_backup.TelegramUpdateHandler;
import com.github.badoualy.telegram.api.Kotlogram; import com.github.badoualy.telegram.api.Kotlogram;
import com.github.badoualy.telegram.api.TelegramApp; import com.github.badoualy.telegram.api.TelegramApp;
import com.github.badoualy.telegram.api.TelegramClient; import com.github.badoualy.telegram.api.TelegramClient;
@ -82,7 +84,8 @@ public class CommandLineController {
storage = new ApiStorage(account); storage = new ApiStorage(account);
TelegramClient client = Kotlogram.getDefaultClient(app, storage); TelegramUpdateHandler handler = new TelegramUpdateHandler();
TelegramClient client = Kotlogram.getDefaultClient(app, storage, Kotlogram.PROD_DC4, handler);
try { try {
user = new UserManager(client); user = new UserManager(client);
@ -112,11 +115,16 @@ public class CommandLineController {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
if (options.cmd_daemon) {
handler.setUser(user);
System.out.println("DAEMON mode requested - keeping running.");
} else {
client.close(); client.close();
}
System.out.println("----- EXIT -----"); System.out.println("----- EXIT -----");
System.out.println("If this program doesn't exit by itself, please press Ctrl-C now."); System.out.println("If this program doesn't exit by itself, please press Ctrl-C now.");
} }
}
}
private void cmd_login() throws RpcErrorException, IOException { private void cmd_login() throws RpcErrorException, IOException {
System.out.println("Please enter your phone number in international format."); System.out.println("Please enter your phone number in international format.");
@ -167,6 +175,7 @@ public class CommandLineController {
System.out.println(" -e, --export <format> Export the database. Valid formats are:"); System.out.println(" -e, --export <format> Export the database. Valid formats are:");
System.out.println(" html - Creates HTML files."); System.out.println(" html - Creates HTML files.");
System.out.println(" --license Displays the license of this program."); System.out.println(" --license Displays the license of this program.");
System.out.println(" -d, --daemon Keep running and automatically save new messages.");
} }
private void list_accounts() { private void list_accounts() {

View File

@ -28,6 +28,7 @@ class CommandLineOptions {
public boolean cmd_version = false; public boolean cmd_version = false;
public String export = null; public String export = null;
public boolean cmd_license = false; public boolean cmd_license = false;
public boolean cmd_daemon = false;
public CommandLineOptions(String[] args) { public CommandLineOptions(String[] args) {
String last_cmd = null; String last_cmd = null;
@ -86,6 +87,9 @@ class CommandLineOptions {
case "--license": case "--license":
this.cmd_license = true; break; this.cmd_license = true; break;
case "-d": case "--daemon":
this.cmd_daemon = true; break;
default: default:
throw new RuntimeException("Unknown command " + arg); throw new RuntimeException("Unknown command " + arg);
} }

View File

@ -41,7 +41,12 @@ class Database {
private UserManager user_manager; private UserManager user_manager;
public Database(UserManager user_manager) { public Database(UserManager user_manager) {
this(user_manager, true);
}
public Database(UserManager user_manager, boolean update_db) {
this.user_manager = user_manager; this.user_manager = user_manager;
System.out.println("Opening database...");
try { try {
Class.forName("org.sqlite.JDBC"); Class.forName("org.sqlite.JDBC");
} catch(ClassNotFoundException e) { } catch(ClassNotFoundException e) {
@ -59,12 +64,14 @@ class Database {
CommandLineController.show_error("Could not connect to SQLITE database."); CommandLineController.show_error("Could not connect to SQLITE database.");
} }
this.init(); this.init(update_db);
System.out.println("Database is ready.");
} }
private void init() { private void init(boolean update_db) {
if (!update_db) return;
try { try {
System.out.println("Opening database...");
int version; int version;
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='database_versions'"); ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='database_versions'");
rs.next(); rs.next();
@ -137,7 +144,6 @@ class Database {
version = 5; version = 5;
} }
System.out.println("Database is ready.");
} catch (SQLException e) { } catch (SQLException e) {
System.out.println(e.getSQLState()); System.out.println(e.getSQLState());
e.printStackTrace(); e.printStackTrace();
@ -203,7 +209,7 @@ class Database {
} }
} }
public void saveMessages(TLVector<TLAbsMessage> all) { public synchronized void saveMessages(TLVector<TLAbsMessage> all) {
try { try {
PreparedStatement ps = conn.prepareStatement( PreparedStatement ps = conn.prepareStatement(
"INSERT OR REPLACE INTO messages " + "INSERT OR REPLACE INTO messages " +
@ -312,7 +318,7 @@ class Database {
} }
} }
public void saveChats(TLVector<TLAbsChat> all) { public synchronized void saveChats(TLVector<TLAbsChat> all) {
try { try {
PreparedStatement ps_insert_or_replace = conn.prepareStatement( PreparedStatement ps_insert_or_replace = conn.prepareStatement(
"INSERT OR REPLACE INTO chats " + "INSERT OR REPLACE INTO chats " +
@ -365,7 +371,7 @@ class Database {
} }
} }
public void saveUsers(TLVector<TLAbsUser> all) { public synchronized void saveUsers(TLVector<TLAbsUser> all) {
try { try {
PreparedStatement ps_insert_or_replace = conn.prepareStatement( PreparedStatement ps_insert_or_replace = conn.prepareStatement(
"INSERT OR REPLACE INTO users " + "INSERT OR REPLACE INTO users " +

View File

@ -182,8 +182,12 @@ class DownloadManager {
LinkedList<TLMessage> messages = this.db.getMessagesWithMedia(); LinkedList<TLMessage> messages = this.db.getMessagesWithMedia();
prog.onMediaDownloadStart(messages.size()); prog.onMediaDownloadStart(messages.size());
for (TLMessage msg : messages) { for (TLMessage msg : messages) {
TLAbsMessageMedia media = msg.getMedia(); downloadSingleMessageMedia(msg, msg.getMedia());
}
prog.onMediaDownloadFinished();
}
public void downloadSingleMessageMedia(TLMessage msg, TLAbsMessageMedia media) throws RpcErrorException, IOException {
if (media instanceof TLMessageMediaPhoto) { if (media instanceof TLMessageMediaPhoto) {
this.downloadMessageMediaPhoto(msg, (TLMessageMediaPhoto)media); this.downloadMessageMediaPhoto(msg, (TLMessageMediaPhoto)media);
} else if (media instanceof TLMessageMediaDocument) { } else if (media instanceof TLMessageMediaDocument) {
@ -205,8 +209,6 @@ class DownloadManager {
throw new RuntimeException("Unexpected " + media.getClass().getName()); throw new RuntimeException("Unexpected " + media.getClass().getName());
} }
} }
prog.onMediaDownloadFinished();
}
private void downloadMessageMediaPhoto(TLMessage msg, TLMessageMediaPhoto p) throws RpcErrorException, IOException { private void downloadMessageMediaPhoto(TLMessage msg, TLMessageMediaPhoto p) throws RpcErrorException, IOException {
if (p.getPhoto() instanceof TLPhoto) { if (p.getPhoto() instanceof TLPhoto) {

View File

@ -0,0 +1,138 @@
/* Telegram_Backup
* Copyright (C) 2016 Fabian Schlenz
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
package de.fabianonline.telegram_backup;
import com.github.badoualy.telegram.api.UpdateCallback;
import com.github.badoualy.telegram.api.TelegramClient;
import com.github.badoualy.telegram.tl.api.*;
import com.github.badoualy.telegram.tl.core.TLVector;
import de.fabianonline.telegram_backup.Database;
import de.fabianonline.telegram_backup.UserManager;
class TelegramUpdateHandler implements UpdateCallback {
private UserManager user = null;
private Database db = null;
public void setUser(UserManager user) { this.user = user; this.db = new Database(user, false);}
public void onUpdates(TelegramClient c, TLUpdates u) {
System.out.println("onUpdates - " + u.getUpdates().size() + " Updates, " + u.getUsers().size() + " Users, " + u.getChats().size() + " Chats");
for(TLAbsUpdate update : u.getUpdates()) {
processUpdate(update, c);
System.out.println(" " + update.getClass().getName());
}
db.saveUsers(u.getUsers());
db.saveChats(u.getChats());
}
public void onUpdatesCombined(TelegramClient c, TLUpdatesCombined u) {
System.out.println("onUpdatesCombined");
for(TLAbsUpdate update : u.getUpdates()) {
processUpdate(update, c);
}
db.saveUsers(u.getUsers());
db.saveChats(u.getChats());
}
public void onUpdateShort(TelegramClient c, TLUpdateShort u) {
System.out.println("onUpdateShort");
processUpdate(u.getUpdate(), c);
System.out.println(" " + u.getUpdate().getClass().getName());
}
public void onShortChatMessage(TelegramClient c, TLUpdateShortChatMessage m) {
System.out.println("onShortChatMessage - " + m.getMessage());
TLMessage msg = new TLMessage(
m.getUnread(),
m.getOut(),
m.getMentioned(),
m.getMediaUnread(),
m.getId(),
m.getFromId(),
new TLPeerChat(m.getChatId()),
m.getFwdFromId(),
m.getFwdDate(),
m.getViaBotId(),
m.getReplyToMsgId(),
m.getDate(),
m.getMessage(),
null,
null,
m.getEntities(),
null);
TLVector<TLAbsMessage> vector = new TLVector<TLAbsMessage>(TLAbsMessage.class);
vector.add(msg);
db.saveMessages(vector);
}
public void onShortMessage(TelegramClient c, TLUpdateShortMessage m) {
System.out.println("onShortMessage - " + m.getOut() + " - " + m.getUserId() + " - " + m.getMessage());
int from_id, to_id;
if (m.getOut()==true) {
from_id = user.getUser().getId();
to_id = m.getUserId();
} else {
to_id = user.getUser().getId();
from_id = m.getUserId();
}
TLMessage msg = new TLMessage(
m.getUnread(),
m.getOut(),
m.getMentioned(),
m.getMediaUnread(),
m.getId(),
from_id,
new TLPeerUser(to_id),
m.getFwdFromId(),
m.getFwdDate(),
m.getViaBotId(),
m.getReplyToMsgId(),
m.getDate(),
m.getMessage(),
null,
null,
m.getEntities(),
null);
TLVector<TLAbsMessage> vector = new TLVector<TLAbsMessage>(TLAbsMessage.class);
vector.add(msg);
db.saveMessages(vector);
}
public void onShortSentMessage(TelegramClient c, TLUpdateShortSentMessage m) { System.out.println("onShortSentMessage"); }
public void onUpdateTooLong(TelegramClient c) { System.out.println("onUpdateTooLong"); }
private void processUpdate(TLAbsUpdate update, TelegramClient client) {
if (update instanceof TLUpdateNewMessage) {
TLAbsMessage abs_msg = ((TLUpdateNewMessage)update).getMessage();
TLVector<TLAbsMessage> vector = new TLVector<TLAbsMessage>(TLAbsMessage.class);
vector.add(abs_msg);
db.saveMessages(vector);
if (abs_msg instanceof TLMessage && ((TLMessage)abs_msg).getMedia()!=null) {
try {
new DownloadManager(user, client, new CommandLineDownloadProgress()).downloadSingleMessageMedia((TLMessage)abs_msg, ((TLMessage)abs_msg).getMedia());
} catch (Exception e) {
System.out.println("We got an exception while downloading media, but we're going to ignore it.");
System.out.println("Here it is anyway:");
e.printStackTrace();
}
}
} else {
// ignore everything else...
}
}
}