mirror of
https://github.com/fabianonline/telegram_backup.git
synced 2024-12-25 22:35:35 +00:00
Added beginnings of an HTMLExporter.
This commit is contained in:
parent
cf6ffc4c60
commit
c8e33fa319
@ -29,9 +29,8 @@ public class CommandLineController {
|
||||
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();
|
||||
|
||||
app = new TelegramApp(Config.APP_ID, Config.APP_HASH, Config.APP_MODEL, Config.APP_SYSVER, Config.APP_APPVER, Config.APP_LANG);
|
||||
@ -60,12 +59,23 @@ public class CommandLineController {
|
||||
"Use '--list-accounts' to see all available accounts.");
|
||||
}
|
||||
|
||||
|
||||
storage = new ApiStorage(account);
|
||||
TelegramClient client = Kotlogram.getDefaultClient(app, storage);
|
||||
|
||||
try {
|
||||
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) {
|
||||
System.out.println("Please enter your phone number in international format.");
|
||||
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(" --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(" -e, --export <format> Export the database. Valid formats are:");
|
||||
System.out.println(" html - Creates HTML files.");
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ class CommandLineOptions {
|
||||
public Integer limit_messages = null;
|
||||
public String target = null;
|
||||
public boolean cmd_version = false;
|
||||
public String export = null;
|
||||
|
||||
public CommandLineOptions(String[] args) {
|
||||
String last_cmd = null;
|
||||
@ -26,6 +27,9 @@ class CommandLineOptions {
|
||||
case "--target":
|
||||
this.target = arg;
|
||||
break;
|
||||
case "--export":
|
||||
this.export = arg;
|
||||
break;
|
||||
}
|
||||
last_cmd = null;
|
||||
continue;
|
||||
@ -57,7 +61,10 @@ class CommandLineOptions {
|
||||
last_cmd = "--target"; continue;
|
||||
|
||||
case "-V": case "--version":
|
||||
this.cmd_version = true; continue;
|
||||
this.cmd_version = true; break;
|
||||
|
||||
case "-e": case "--export":
|
||||
last_cmd = "--export"; continue;
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Unknown command " + arg);
|
||||
|
@ -10,11 +10,11 @@ import java.sql.SQLException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.Types;
|
||||
import java.sql.Time;
|
||||
import java.io.File;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.LinkedList;
|
||||
import java.sql.Array;
|
||||
|
||||
import de.fabianonline.telegram_backup.UserManager;
|
||||
import de.fabianonline.telegram_backup.StickerConverter;
|
||||
@ -98,6 +98,21 @@ class Database {
|
||||
stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (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.");
|
||||
} catch (SQLException e) {
|
||||
@ -264,12 +279,12 @@ class Database {
|
||||
public void saveChats(TLVector<TLAbsChat> all) {
|
||||
try {
|
||||
PreparedStatement ps_insert_or_replace = conn.prepareStatement(
|
||||
"INSERT OR REPLACE INTO dialogs " +
|
||||
"INSERT OR REPLACE INTO chats " +
|
||||
"(id, name, type) "+
|
||||
"VALUES " +
|
||||
"(?, ?, ?)");
|
||||
PreparedStatement ps_insert_or_ignore = conn.prepareStatement(
|
||||
"INSERT OR IGNORE INTO dialogs " +
|
||||
"INSERT OR IGNORE INTO chats " +
|
||||
"(id, name, type) "+
|
||||
"VALUES " +
|
||||
"(?, ?, ?)");
|
||||
@ -378,4 +393,127 @@ class Database {
|
||||
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.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
class DownloadManager {
|
||||
UserManager user;
|
||||
@ -84,23 +87,27 @@ class DownloadManager {
|
||||
|
||||
System.out.println("Checking message database for completeness...");
|
||||
if (db.getMessageCount() != db.getTopMessageID()) {
|
||||
LinkedList<Integer> ids = db.getMissingIDs();
|
||||
System.out.println("Downloading " + ids.size() + " messages that are missing in your database.");
|
||||
prog.onMessageDownloadStart(ids.size());
|
||||
while (ids.size()>0) {
|
||||
TLIntVector vector = new TLIntVector();
|
||||
for (int i=0; i<100; i++) {
|
||||
if (ids.size()==0) break;
|
||||
vector.add(ids.remove());
|
||||
if (limit != null) {
|
||||
System.out.println("You are missing messages in your database. But since you're using '--limit-messages', I won't download these now.");
|
||||
} else {
|
||||
LinkedList<Integer> ids = db.getMissingIDs();
|
||||
System.out.println("Downloading " + ids.size() + " messages that are missing in your database.");
|
||||
prog.onMessageDownloadStart(ids.size());
|
||||
while (ids.size()>0) {
|
||||
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.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();
|
||||
}
|
||||
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