de.fabianonline.telegram_backup.exporter.HTMLExporter.java Source code

Java tutorial

Introduction

Here is the source code for de.fabianonline.telegram_backup.exporter.HTMLExporter.java

Source

/* 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.exporter;

import de.fabianonline.telegram_backup.UserManager;
import de.fabianonline.telegram_backup.Database;
import de.fabianonline.telegram_backup.Utils;

import java.io.File;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
import java.nio.charset.Charset;
import java.io.FileWriter;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.net.URL;
import org.apache.commons.io.FileUtils;
import java.util.LinkedList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import com.github.mustachejava.MustacheFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HTMLExporter {
    private static Logger logger = LoggerFactory.getLogger(HTMLExporter.class);

    public void export(UserManager user) {
        try {
            Database db = new Database(user, null);

            // Create base dir
            logger.debug("Creating base dir");
            String base = user.getFileBase() + "files" + File.separatorChar;
            new File(base).mkdirs();
            new File(base + "dialogs").mkdirs();

            logger.debug("Fetching dialogs");
            LinkedList<Database.Dialog> dialogs = db.getListOfDialogsForExport();
            logger.trace("Got {} dialogs", dialogs.size());
            logger.debug("Fetching chats");
            LinkedList<Database.Chat> chats = db.getListOfChatsForExport();
            logger.trace("Got {} chats", chats.size());

            logger.debug("Generating index.html");
            HashMap<String, Object> scope = new HashMap<String, Object>();
            scope.put("user", user);
            scope.put("dialogs", dialogs);
            scope.put("chats", chats);

            // Collect stats data
            scope.put("count.chats", chats.size());
            scope.put("count.dialogs", dialogs.size());

            int count_messages_chats = 0;
            int count_messages_dialogs = 0;
            for (Database.Chat c : chats)
                count_messages_chats += c.count;
            for (Database.Dialog d : dialogs)
                count_messages_dialogs += d.count;

            scope.put("count.messages", count_messages_chats + count_messages_dialogs);
            scope.put("count.messages.chats", count_messages_chats);
            scope.put("count.messages.dialogs", count_messages_dialogs);

            scope.put("count.messages.from_me", db.getMessagesFromUserCount());

            scope.put("heatmap_data", intArrayToString(db.getMessageTimesMatrix()));

            scope.putAll(db.getMessageAuthorsWithCount());
            scope.putAll(db.getMessageTypesWithCount());
            scope.putAll(db.getMessageMediaTypesWithCount());

            MustacheFactory mf = new DefaultMustacheFactory();
            Mustache mustache = mf.compile("templates/html/index.mustache");
            OutputStreamWriter w = getWriter(base + "index.html");
            mustache.execute(w, scope);
            w.close();

            mustache = mf.compile("templates/html/chat.mustache");

            int i = 0;
            logger.debug("Generating {} dialog pages", dialogs.size());
            for (Database.Dialog d : dialogs) {
                i++;
                logger.trace("Dialog {}/{}: {}", i, dialogs.size(), Utils.anonymize("" + d.id));
                LinkedList<HashMap<String, Object>> messages = db.getMessagesForExport(d);
                scope.clear();
                scope.put("user", user);
                scope.put("dialog", d);
                scope.put("messages", messages);

                scope.putAll(db.getMessageAuthorsWithCount(d));
                scope.put("heatmap_data", intArrayToString(db.getMessageTimesMatrix(d)));
                scope.putAll(db.getMessageTypesWithCount(d));
                scope.putAll(db.getMessageMediaTypesWithCount(d));

                w = getWriter(base + "dialogs" + File.separatorChar + "user_" + d.id + ".html");
                mustache.execute(w, scope);
                w.close();
            }

            i = 0;
            logger.debug("Generating {} chat pages", chats.size());
            for (Database.Chat c : chats) {
                i++;
                logger.trace("Chat {}/{}: {}", i, chats.size(), Utils.anonymize("" + c.id));
                LinkedList<HashMap<String, Object>> messages = db.getMessagesForExport(c);
                scope.clear();
                scope.put("user", user);
                scope.put("chat", c);
                scope.put("messages", messages);

                scope.putAll(db.getMessageAuthorsWithCount(c));
                scope.put("heatmap_data", intArrayToString(db.getMessageTimesMatrix(c)));
                scope.putAll(db.getMessageTypesWithCount(c));
                scope.putAll(db.getMessageMediaTypesWithCount(c));

                w = getWriter(base + "dialogs" + File.separatorChar + "chat_" + c.id + ".html");
                mustache.execute(w, scope);
                w.close();
            }

            logger.debug("Generating additional files");
            // Copy CSS
            URL cssFile = getClass().getResource("/templates/html/style.css");
            File dest = new File(base + "style.css");
            FileUtils.copyURLToFile(cssFile, dest);
            logger.debug("Done exporting.");
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Exception above!");
        }
    }

    private OutputStreamWriter getWriter(String filename) throws FileNotFoundException {
        logger.trace("Creating writer for file {}", Utils.anonymize(filename));
        return new OutputStreamWriter(new FileOutputStream(filename), Charset.forName("UTF-8").newEncoder());
    }

    private String intArrayToString(int[][] data) {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int x = 0; x < data.length; x++) {
            for (int y = 0; y < data[x].length; y++) {
                if (x > 0 || y > 0)
                    sb.append(",");
                sb.append("[" + x + "," + y + "," + data[x][y] + "]");
            }
        }
        sb.append("]");
        return sb.toString();
    }

    private String mapToString(Map<String, Integer> map) {
        StringBuilder sb = new StringBuilder("[");
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            sb.append("['" + entry.getKey() + "', " + entry.getValue() + "],");
        }
        sb.append("]");
        return sb.toString();
    }
}