mirror of
https://github.com/fabianonline/telegram_backup.git
synced 2024-11-23 01:06:17 +00:00
Added beginnings of an HTMLExporter.
This commit is contained in:
parent
cf6ffc4c60
commit
c8e33fa319
@ -29,8 +29,7 @@ public class CommandLineController {
|
|||||||
Config.FILE_BASE = options.target;
|
Config.FILE_BASE = options.target;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Target directory for files: " + Config.FILE_BASE);
|
System.out.println("Base directory for files: " + Config.FILE_BASE);
|
||||||
|
|
||||||
|
|
||||||
if (options.cmd_list_accounts) this.list_accounts();
|
if (options.cmd_list_accounts) this.list_accounts();
|
||||||
|
|
||||||
@ -60,12 +59,23 @@ public class CommandLineController {
|
|||||||
"Use '--list-accounts' to see all available accounts.");
|
"Use '--list-accounts' to see all available accounts.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
storage = new ApiStorage(account);
|
storage = new ApiStorage(account);
|
||||||
TelegramClient client = Kotlogram.getDefaultClient(app, storage);
|
TelegramClient client = Kotlogram.getDefaultClient(app, storage);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
user = new UserManager(client);
|
user = new UserManager(client);
|
||||||
|
|
||||||
|
if (options.export != null) {
|
||||||
|
if (options.export.toLowerCase().equals("html")) {
|
||||||
|
(new HTMLExporter()).export(user);
|
||||||
|
System.exit(0);
|
||||||
|
} else {
|
||||||
|
show_error("Unknown export format.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (options.cmd_login) {
|
if (options.cmd_login) {
|
||||||
System.out.println("Please enter your phone number in international format.");
|
System.out.println("Please enter your phone number in international format.");
|
||||||
System.out.println("Example: +4917077651234");
|
System.out.println("Example: +4917077651234");
|
||||||
@ -114,6 +124,8 @@ public class CommandLineController {
|
|||||||
System.out.println(" -A, --list-accounts List all existing accounts ");
|
System.out.println(" -A, --list-accounts List all existing accounts ");
|
||||||
System.out.println(" --limit-messages <x> Downloads at most the most recent <x> messages.");
|
System.out.println(" --limit-messages <x> Downloads at most the most recent <x> messages.");
|
||||||
System.out.println(" -t, --target <x> Target directory for the files.");
|
System.out.println(" -t, --target <x> Target directory for the files.");
|
||||||
|
System.out.println(" -e, --export <format> Export the database. Valid formats are:");
|
||||||
|
System.out.println(" html - Creates HTML files.");
|
||||||
|
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ class CommandLineOptions {
|
|||||||
public Integer limit_messages = null;
|
public Integer limit_messages = null;
|
||||||
public String target = null;
|
public String target = null;
|
||||||
public boolean cmd_version = false;
|
public boolean cmd_version = false;
|
||||||
|
public String export = null;
|
||||||
|
|
||||||
public CommandLineOptions(String[] args) {
|
public CommandLineOptions(String[] args) {
|
||||||
String last_cmd = null;
|
String last_cmd = null;
|
||||||
@ -26,6 +27,9 @@ class CommandLineOptions {
|
|||||||
case "--target":
|
case "--target":
|
||||||
this.target = arg;
|
this.target = arg;
|
||||||
break;
|
break;
|
||||||
|
case "--export":
|
||||||
|
this.export = arg;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
last_cmd = null;
|
last_cmd = null;
|
||||||
continue;
|
continue;
|
||||||
@ -57,7 +61,10 @@ class CommandLineOptions {
|
|||||||
last_cmd = "--target"; continue;
|
last_cmd = "--target"; continue;
|
||||||
|
|
||||||
case "-V": case "--version":
|
case "-V": case "--version":
|
||||||
this.cmd_version = true; continue;
|
this.cmd_version = true; break;
|
||||||
|
|
||||||
|
case "-e": case "--export":
|
||||||
|
last_cmd = "--export"; continue;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unknown command " + arg);
|
throw new RuntimeException("Unknown command " + arg);
|
||||||
|
@ -10,11 +10,11 @@ import java.sql.SQLException;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.sql.Time;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.sql.Array;
|
|
||||||
|
|
||||||
import de.fabianonline.telegram_backup.UserManager;
|
import de.fabianonline.telegram_backup.UserManager;
|
||||||
import de.fabianonline.telegram_backup.StickerConverter;
|
import de.fabianonline.telegram_backup.StickerConverter;
|
||||||
@ -98,6 +98,21 @@ class Database {
|
|||||||
stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (2)");
|
stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (2)");
|
||||||
version = 2;
|
version = 2;
|
||||||
}
|
}
|
||||||
|
if (version==2) {
|
||||||
|
System.out.println(" Updating to version 3...");
|
||||||
|
stmt.executeUpdate("ALTER TABLE dialogs RENAME TO 'chats'");
|
||||||
|
stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (3)");
|
||||||
|
version = 3;
|
||||||
|
}
|
||||||
|
if (version==3) {
|
||||||
|
System.out.println(" Updating to version 4...");
|
||||||
|
stmt.executeUpdate("CREATE TABLE messages_new (id INTEGER PRIMARY KEY ASC, dialog_id INTEGER, to_id INTEGER, from_id INTEGER, from_type TEXT, text TEXT, time INTEGER, has_media BOOLEAN, sticker TEXT, data BLOB,type TEXT);");
|
||||||
|
stmt.executeUpdate("INSERT INTO messages_new SELECT * FROM messages");
|
||||||
|
stmt.executeUpdate("DROP TABLE messages");
|
||||||
|
stmt.executeUpdate("ALTER TABLE messages_new RENAME TO 'messages'");
|
||||||
|
stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (4)");
|
||||||
|
version = 4;
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println("Database is ready.");
|
System.out.println("Database is ready.");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@ -264,12 +279,12 @@ class Database {
|
|||||||
public void saveChats(TLVector<TLAbsChat> all) {
|
public 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 dialogs " +
|
"INSERT OR REPLACE INTO chats " +
|
||||||
"(id, name, type) "+
|
"(id, name, type) "+
|
||||||
"VALUES " +
|
"VALUES " +
|
||||||
"(?, ?, ?)");
|
"(?, ?, ?)");
|
||||||
PreparedStatement ps_insert_or_ignore = conn.prepareStatement(
|
PreparedStatement ps_insert_or_ignore = conn.prepareStatement(
|
||||||
"INSERT OR IGNORE INTO dialogs " +
|
"INSERT OR IGNORE INTO chats " +
|
||||||
"(id, name, type) "+
|
"(id, name, type) "+
|
||||||
"VALUES " +
|
"VALUES " +
|
||||||
"(?, ?, ?)");
|
"(?, ?, ?)");
|
||||||
@ -378,4 +393,127 @@ class Database {
|
|||||||
throw new RuntimeException("Exception occured. See above.");
|
throw new RuntimeException("Exception occured. See above.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LinkedList<Chat> getListOfChatsForExport() {
|
||||||
|
LinkedList<Chat> list = new LinkedList<Chat>();
|
||||||
|
try {
|
||||||
|
ResultSet rs = stmt.executeQuery("SELECT chats.id, chats.name, COUNT(messages.id) as c "+
|
||||||
|
"FROM chats, messages WHERE messages.from_type='chat' AND messages.dialog_id=chats.id "+
|
||||||
|
"GROUP BY chats.id ORDER BY c DESC");
|
||||||
|
while (rs.next()) {
|
||||||
|
list.add(new Chat(rs.getInt(1), rs.getString(2), rs.getInt(3)));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
return list;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException("Exception above!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkedList<Dialog> getListOfDialogsForExport() {
|
||||||
|
LinkedList<Dialog> list = new LinkedList<Dialog>();
|
||||||
|
try {
|
||||||
|
ResultSet rs = stmt.executeQuery(
|
||||||
|
"SELECT users.id, first_name, last_name, username, COUNT(messages.id) as c " +
|
||||||
|
"FROM users, messages WHERE messages.from_type='user' AND messages.dialog_id=users.id " +
|
||||||
|
"GROUP BY users.id ORDER BY c DESC");
|
||||||
|
while (rs.next()) {
|
||||||
|
list.add(new Dialog(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getInt(5)));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
return list;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException("Exception above!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getMessagesForExport(Dialog d, ChatMessageProcessor p) {
|
||||||
|
getMessagesForExport("user", d.id, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getMessagesForExport(Chat c, ChatMessageProcessor p) {
|
||||||
|
getMessagesForExport("chat", c.id, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getMessagesForExport(String type, Integer id, ChatMessageProcessor p) {
|
||||||
|
try {
|
||||||
|
ResultSet rs = stmt.executeQuery("SELECT messages.id, text, time, has_media, " +
|
||||||
|
"sticker, first_name, last_name, username FROM messages, users WHERE " +
|
||||||
|
"users.id=messages.from_id AND dialog_id=" + id + " AND from_type='" + type + "' " +
|
||||||
|
"ORDER BY messages.id");
|
||||||
|
while (rs.next()) {
|
||||||
|
Message m = new Message(
|
||||||
|
rs.getInt(1),
|
||||||
|
rs.getString(2),
|
||||||
|
rs.getTime(3),
|
||||||
|
rs.getBoolean(4),
|
||||||
|
rs.getString(5),
|
||||||
|
rs.getString(6),
|
||||||
|
rs.getString(7),
|
||||||
|
rs.getString(8));
|
||||||
|
p.process(m);
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
} catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException("Exception above!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class Dialog {
|
||||||
|
public int id;
|
||||||
|
public String first_name;
|
||||||
|
public String last_name;
|
||||||
|
public String username;
|
||||||
|
public int count;
|
||||||
|
|
||||||
|
public Dialog (int id, String first_name, String last_name, String username, int count) {
|
||||||
|
this.id = id;
|
||||||
|
this.first_name = first_name;
|
||||||
|
this.last_name = last_name;
|
||||||
|
this.username = username;
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Chat {
|
||||||
|
public int id;
|
||||||
|
public String name;
|
||||||
|
public int count;
|
||||||
|
|
||||||
|
public Chat(int id, String name, int count) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Message {
|
||||||
|
public int id;
|
||||||
|
public String text;
|
||||||
|
public Time time;
|
||||||
|
public boolean has_media;
|
||||||
|
public String sticker;
|
||||||
|
public String first_name;
|
||||||
|
public String last_name;
|
||||||
|
public String username;
|
||||||
|
|
||||||
|
public Message(int i, String t, Time t2, boolean m, String st, String n1, String n2, String n3) {
|
||||||
|
this.id = i;
|
||||||
|
this.text = t;
|
||||||
|
this.time = t2;
|
||||||
|
this.has_media = m;
|
||||||
|
this.sticker = st;
|
||||||
|
this.first_name = n1;
|
||||||
|
this.last_name = n2;
|
||||||
|
this.username = n3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ChatMessageProcessor {
|
||||||
|
public void process(Message msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,9 @@ import java.io.File;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
class DownloadManager {
|
class DownloadManager {
|
||||||
UserManager user;
|
UserManager user;
|
||||||
@ -84,23 +87,27 @@ class DownloadManager {
|
|||||||
|
|
||||||
System.out.println("Checking message database for completeness...");
|
System.out.println("Checking message database for completeness...");
|
||||||
if (db.getMessageCount() != db.getTopMessageID()) {
|
if (db.getMessageCount() != db.getTopMessageID()) {
|
||||||
LinkedList<Integer> ids = db.getMissingIDs();
|
if (limit != null) {
|
||||||
System.out.println("Downloading " + ids.size() + " messages that are missing in your database.");
|
System.out.println("You are missing messages in your database. But since you're using '--limit-messages', I won't download these now.");
|
||||||
prog.onMessageDownloadStart(ids.size());
|
} else {
|
||||||
while (ids.size()>0) {
|
LinkedList<Integer> ids = db.getMissingIDs();
|
||||||
TLIntVector vector = new TLIntVector();
|
System.out.println("Downloading " + ids.size() + " messages that are missing in your database.");
|
||||||
for (int i=0; i<100; i++) {
|
prog.onMessageDownloadStart(ids.size());
|
||||||
if (ids.size()==0) break;
|
while (ids.size()>0) {
|
||||||
vector.add(ids.remove());
|
TLIntVector vector = new TLIntVector();
|
||||||
|
for (int i=0; i<100; i++) {
|
||||||
|
if (ids.size()==0) break;
|
||||||
|
vector.add(ids.remove());
|
||||||
|
}
|
||||||
|
TLAbsMessages response = client.messagesGetMessages(vector);
|
||||||
|
prog.onMessageDownloaded(response.getMessages().size());
|
||||||
|
db.saveMessages(response.getMessages());
|
||||||
|
db.saveChats(response.getChats());
|
||||||
|
db.saveUsers(response.getUsers());
|
||||||
|
try { Thread.sleep(Config.DELAY_AFTER_GET_MESSAGES); } catch (InterruptedException e) {}
|
||||||
}
|
}
|
||||||
TLAbsMessages response = client.messagesGetMessages(vector);
|
prog.onMessageDownloadFinished();
|
||||||
prog.onMessageDownloaded(response.getMessages().size());
|
|
||||||
db.saveMessages(response.getMessages());
|
|
||||||
db.saveChats(response.getChats());
|
|
||||||
db.saveUsers(response.getUsers());
|
|
||||||
try { Thread.sleep(Config.DELAY_AFTER_GET_MESSAGES); } catch (InterruptedException e) {}
|
|
||||||
}
|
}
|
||||||
prog.onMessageDownloadFinished();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
package de.fabianonline.telegram_backup;
|
||||||
|
|
||||||
|
import de.fabianonline.telegram_backup.UserManager;
|
||||||
|
import de.fabianonline.telegram_backup.Database;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import org.javatuples.Triplet;
|
||||||
|
|
||||||
|
class HTMLExporter {
|
||||||
|
public void export(UserManager user) {
|
||||||
|
try {
|
||||||
|
Database db = new Database(user);
|
||||||
|
|
||||||
|
// Create base dir
|
||||||
|
String base = user.getFileBase() + "export" + File.separatorChar + "html" + File.separatorChar;
|
||||||
|
new File(base).mkdirs();
|
||||||
|
new File(base + "dialogs").mkdirs();
|
||||||
|
|
||||||
|
PrintWriter index = new PrintWriter(new BufferedWriter(new FileWriter(base + "index.html")));
|
||||||
|
index.println("<!DOCTYPE html>");
|
||||||
|
index.println("<html>");
|
||||||
|
index.println("<head>");
|
||||||
|
index.println("<title>Telegram Backup for " + user.getUserString() + "</title>");
|
||||||
|
index.println("</head>");
|
||||||
|
|
||||||
|
index.println("<body>");
|
||||||
|
index.println("<h1>Telegram Backup</h1>");
|
||||||
|
index.println("<h2>" + user.getUserString() + "</h2>");
|
||||||
|
LinkedList<Database.Dialog> dialogs = db.getListOfDialogsForExport();
|
||||||
|
index.println("<h3>Dialogs</h3>");
|
||||||
|
index.println("<ul>");
|
||||||
|
for (Database.Dialog dialog : dialogs) {
|
||||||
|
index.println("<li><a href='dialogs/user_" + dialog.id + ".html'>" + dialog.first_name + " " + (dialog.last_name!=null ? dialog.last_name : "") + "</a> <span class='count'>(" + dialog.count + ")</span></li>");
|
||||||
|
String filename = base + "dialogs" + File.separatorChar + "user_" + dialog.id + ".html";
|
||||||
|
final PrintWriter chatfile = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
|
||||||
|
db.getMessagesForExport(dialog, new ChatLineWriter(chatfile));
|
||||||
|
chatfile.close();
|
||||||
|
}
|
||||||
|
LinkedList<Database.Chat> chats = db.getListOfChatsForExport();
|
||||||
|
index.println("<h3>Group chats</h3>");
|
||||||
|
index.println("<ul>");
|
||||||
|
for (Database.Chat chat : chats) {
|
||||||
|
index.println("<li><a href='dialogs/chat_" + chat.id + ".html'>" + chat.name + "</a> <span class='count'>(" + chat.count + ")</span></li>");
|
||||||
|
String filename = base + "dialogs" + File.separatorChar + "chat_" + chat.id + ".html";
|
||||||
|
final PrintWriter chatfile = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
|
||||||
|
db.getMessagesForExport(chat, new ChatLineWriter(chatfile));
|
||||||
|
chatfile.close();
|
||||||
|
}
|
||||||
|
index.println("</ul>");
|
||||||
|
index.println("</body>");
|
||||||
|
index.println("</html>");
|
||||||
|
index.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException("Exception above!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChatLineWriter implements Database.ChatMessageProcessor {
|
||||||
|
PrintWriter w;
|
||||||
|
|
||||||
|
public ChatLineWriter(PrintWriter w) {
|
||||||
|
this.w = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void process(Database.Message msg) {
|
||||||
|
w.println("" + msg.text + "<br>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user