From 515efb2fde6e4de24f3ac9c5594fc971a3dcbd44 Mon Sep 17 00:00:00 2001 From: Fabian Schlenz Date: Wed, 6 Jul 2016 18:07:04 +0200 Subject: [PATCH] WIP: Added Daemon-mode to keep the app running and save new messages in real time. --- .../CommandLineController.java | 17 ++- .../telegram_backup/CommandLineOptions.java | 4 + .../telegram_backup/Database.java | 20 ++- .../telegram_backup/DownloadManager.java | 46 +++--- .../TelegramUpdateHandler.java | 138 ++++++++++++++++++ 5 files changed, 192 insertions(+), 33 deletions(-) create mode 100644 src/main/java/de/fabianonline/telegram_backup/TelegramUpdateHandler.java diff --git a/src/main/java/de/fabianonline/telegram_backup/CommandLineController.java b/src/main/java/de/fabianonline/telegram_backup/CommandLineController.java index 9217c7c..ed26734 100644 --- a/src/main/java/de/fabianonline/telegram_backup/CommandLineController.java +++ b/src/main/java/de/fabianonline/telegram_backup/CommandLineController.java @@ -16,6 +16,8 @@ package de.fabianonline.telegram_backup; +import de.fabianonline.telegram_backup.TelegramUpdateHandler; + import com.github.badoualy.telegram.api.Kotlogram; import com.github.badoualy.telegram.api.TelegramApp; import com.github.badoualy.telegram.api.TelegramClient; @@ -82,7 +84,8 @@ public class CommandLineController { 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 { user = new UserManager(client); @@ -112,10 +115,15 @@ public class CommandLineController { } catch (IOException e) { e.printStackTrace(); } finally { - client.close(); + if (options.cmd_daemon) { + handler.setUser(user); + System.out.println("DAEMON mode requested - keeping running."); + } else { + client.close(); + System.out.println("----- EXIT -----"); + System.out.println("If this program doesn't exit by itself, please press Ctrl-C now."); + } } - System.out.println("----- EXIT -----"); - System.out.println("If this program doesn't exit by itself, please press Ctrl-C now."); } private void cmd_login() throws RpcErrorException, IOException { @@ -167,6 +175,7 @@ public class CommandLineController { System.out.println(" -e, --export Export the database. Valid formats are:"); System.out.println(" html - Creates HTML files."); 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() { diff --git a/src/main/java/de/fabianonline/telegram_backup/CommandLineOptions.java b/src/main/java/de/fabianonline/telegram_backup/CommandLineOptions.java index 2deef38..bdd55cd 100644 --- a/src/main/java/de/fabianonline/telegram_backup/CommandLineOptions.java +++ b/src/main/java/de/fabianonline/telegram_backup/CommandLineOptions.java @@ -28,6 +28,7 @@ class CommandLineOptions { public boolean cmd_version = false; public String export = null; public boolean cmd_license = false; + public boolean cmd_daemon = false; public CommandLineOptions(String[] args) { String last_cmd = null; @@ -85,6 +86,9 @@ class CommandLineOptions { case "--license": this.cmd_license = true; break; + + case "-d": case "--daemon": + this.cmd_daemon = true; break; default: throw new RuntimeException("Unknown command " + arg); diff --git a/src/main/java/de/fabianonline/telegram_backup/Database.java b/src/main/java/de/fabianonline/telegram_backup/Database.java index 274e96b..894b4b1 100644 --- a/src/main/java/de/fabianonline/telegram_backup/Database.java +++ b/src/main/java/de/fabianonline/telegram_backup/Database.java @@ -41,7 +41,12 @@ class Database { private 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; + System.out.println("Opening database..."); try { Class.forName("org.sqlite.JDBC"); } catch(ClassNotFoundException e) { @@ -59,12 +64,14 @@ class 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 { - System.out.println("Opening database..."); int version; ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='database_versions'"); rs.next(); @@ -137,7 +144,6 @@ class Database { version = 5; } - System.out.println("Database is ready."); } catch (SQLException e) { System.out.println(e.getSQLState()); e.printStackTrace(); @@ -203,7 +209,7 @@ class Database { } } - public void saveMessages(TLVector all) { + public synchronized void saveMessages(TLVector all) { try { PreparedStatement ps = conn.prepareStatement( "INSERT OR REPLACE INTO messages " + @@ -312,7 +318,7 @@ class Database { } } - public void saveChats(TLVector all) { + public synchronized void saveChats(TLVector all) { try { PreparedStatement ps_insert_or_replace = conn.prepareStatement( "INSERT OR REPLACE INTO chats " + @@ -365,7 +371,7 @@ class Database { } } - public void saveUsers(TLVector all) { + public synchronized void saveUsers(TLVector all) { try { PreparedStatement ps_insert_or_replace = conn.prepareStatement( "INSERT OR REPLACE INTO users " + diff --git a/src/main/java/de/fabianonline/telegram_backup/DownloadManager.java b/src/main/java/de/fabianonline/telegram_backup/DownloadManager.java index 6b75aa1..d20c301 100644 --- a/src/main/java/de/fabianonline/telegram_backup/DownloadManager.java +++ b/src/main/java/de/fabianonline/telegram_backup/DownloadManager.java @@ -182,32 +182,34 @@ class DownloadManager { LinkedList messages = this.db.getMessagesWithMedia(); prog.onMediaDownloadStart(messages.size()); for (TLMessage msg : messages) { - TLAbsMessageMedia media = msg.getMedia(); - - if (media instanceof TLMessageMediaPhoto) { - this.downloadMessageMediaPhoto(msg, (TLMessageMediaPhoto)media); - } else if (media instanceof TLMessageMediaDocument) { - this.downloadMessageMediaDocument(msg, (TLMessageMediaDocument)media); - } else if (media instanceof TLMessageMediaVideo) { - this.downloadMessageMediaVideo(msg, (TLMessageMediaVideo)media); - } else if (media instanceof TLMessageMediaAudio) { - this.downloadMessageMediaAudio(msg, (TLMessageMediaAudio)media); - } else if (media instanceof TLMessageMediaGeo) { - this.downloadMessageMediaGeo(msg, (TLMessageMediaGeo)media); - } else if (media instanceof TLMessageMediaEmpty || - media instanceof TLMessageMediaUnsupported || - media instanceof TLMessageMediaWebPage || - media instanceof TLMessageMediaContact || - media instanceof TLMessageMediaVenue) { - prog.onMediaDownloadedOther(true); - // do nothing - } else { - throw new RuntimeException("Unexpected " + media.getClass().getName()); - } + downloadSingleMessageMedia(msg, msg.getMedia()); } prog.onMediaDownloadFinished(); } + public void downloadSingleMessageMedia(TLMessage msg, TLAbsMessageMedia media) throws RpcErrorException, IOException { + if (media instanceof TLMessageMediaPhoto) { + this.downloadMessageMediaPhoto(msg, (TLMessageMediaPhoto)media); + } else if (media instanceof TLMessageMediaDocument) { + this.downloadMessageMediaDocument(msg, (TLMessageMediaDocument)media); + } else if (media instanceof TLMessageMediaVideo) { + this.downloadMessageMediaVideo(msg, (TLMessageMediaVideo)media); + } else if (media instanceof TLMessageMediaAudio) { + this.downloadMessageMediaAudio(msg, (TLMessageMediaAudio)media); + } else if (media instanceof TLMessageMediaGeo) { + this.downloadMessageMediaGeo(msg, (TLMessageMediaGeo)media); + } else if (media instanceof TLMessageMediaEmpty || + media instanceof TLMessageMediaUnsupported || + media instanceof TLMessageMediaWebPage || + media instanceof TLMessageMediaContact || + media instanceof TLMessageMediaVenue) { + prog.onMediaDownloadedOther(true); + // do nothing + } else { + throw new RuntimeException("Unexpected " + media.getClass().getName()); + } + } + private void downloadMessageMediaPhoto(TLMessage msg, TLMessageMediaPhoto p) throws RpcErrorException, IOException { if (p.getPhoto() instanceof TLPhoto) { TLPhoto photo = (TLPhoto) p.getPhoto(); diff --git a/src/main/java/de/fabianonline/telegram_backup/TelegramUpdateHandler.java b/src/main/java/de/fabianonline/telegram_backup/TelegramUpdateHandler.java new file mode 100644 index 0000000..ac4482d --- /dev/null +++ b/src/main/java/de/fabianonline/telegram_backup/TelegramUpdateHandler.java @@ -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 . */ + +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 vector = new TLVector(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 vector = new TLVector(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 vector = new TLVector(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... + } + } +}