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:
parent
e1cfaf670e
commit
515efb2fde
@ -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,10 +115,15 @@ public class CommandLineController {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} 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 {
|
private void cmd_login() throws RpcErrorException, IOException {
|
||||||
@ -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() {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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 " +
|
||||||
|
@ -182,32 +182,34 @@ 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());
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
prog.onMediaDownloadFinished();
|
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 {
|
private void downloadMessageMediaPhoto(TLMessage msg, TLMessageMediaPhoto p) throws RpcErrorException, IOException {
|
||||||
if (p.getPhoto() instanceof TLPhoto) {
|
if (p.getPhoto() instanceof TLPhoto) {
|
||||||
TLPhoto photo = (TLPhoto) p.getPhoto();
|
TLPhoto photo = (TLPhoto) p.getPhoto();
|
||||||
|
@ -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...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user