mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2024-09-19 12:18:48 -04:00
Add dark theme and theme switch (#4)
* Add dark theme * Refactor a bit * Add back Light theme and add a switch * Update readme
This commit is contained in:
parent
22d7dd43ec
commit
95d581797b
10 changed files with 288 additions and 135 deletions
|
@ -9,7 +9,9 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Services\ExportTemplate.html" />
|
||||
<EmbeddedResource Include="Resources\HtmlExportService\LightTheme.css" />
|
||||
<EmbeddedResource Include="Resources\HtmlExportService\DarkTheme.css" />
|
||||
<EmbeddedResource Include="Resources\HtmlExportService\Template.html" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -6,10 +6,13 @@
|
|||
|
||||
public string ChannelId { get; }
|
||||
|
||||
public Options(string token, string channelId)
|
||||
public Theme Theme { get; }
|
||||
|
||||
public Options(string token, string channelId, Theme theme)
|
||||
{
|
||||
Token = token;
|
||||
ChannelId = channelId;
|
||||
Theme = theme;
|
||||
}
|
||||
}
|
||||
}
|
8
DiscordChatExporter/Models/Theme.cs
Normal file
8
DiscordChatExporter/Models/Theme.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace DiscordChatExporter.Models
|
||||
{
|
||||
public enum Theme
|
||||
{
|
||||
Light,
|
||||
Dark
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ namespace DiscordChatExporter
|
|||
public static class Program
|
||||
{
|
||||
private static readonly DiscordApiService DiscordApiService = new DiscordApiService();
|
||||
private static readonly ExportService ExportService = new ExportService();
|
||||
private static readonly HtmlExportService HtmlExportService = new HtmlExportService();
|
||||
|
||||
private static Options GetOptions(string[] args)
|
||||
{
|
||||
|
@ -37,8 +37,11 @@ namespace DiscordChatExporter
|
|||
if (token.IsBlank() || channelId.IsBlank())
|
||||
throw new ArgumentException("Some or all required command line arguments are missing");
|
||||
|
||||
// Exract optional arguments
|
||||
var theme = argsDic.GetOrDefault("theme").ParseEnumOrDefault<Theme>();
|
||||
|
||||
// Create option set
|
||||
return new Options(token, channelId);
|
||||
return new Options(token, channelId, theme);
|
||||
}
|
||||
|
||||
private static async Task MainAsync(string[] args)
|
||||
|
@ -53,7 +56,7 @@ namespace DiscordChatExporter
|
|||
|
||||
// Export
|
||||
Console.WriteLine("Exporting messages...");
|
||||
ExportService.Export($"{options.ChannelId}.html", chatLog);
|
||||
HtmlExportService.Export($"{options.ChannelId}.html", chatLog, options.Theme);
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
|
|
105
DiscordChatExporter/Resources/HtmlExportService/DarkTheme.css
Normal file
105
DiscordChatExporter/Resources/HtmlExportService/DarkTheme.css
Normal file
|
@ -0,0 +1,105 @@
|
|||
body {
|
||||
font-family: Whitney, Helvetica Neue, Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
|
||||
background-color: #36393E;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
|
||||
color: #0096CF;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.pre, span.pre {
|
||||
font-family: Consolas, Courier New, Courier, Monospace;
|
||||
|
||||
padding-right: 2px;
|
||||
padding-left: 2px;
|
||||
|
||||
background-color: #2F3136;
|
||||
}
|
||||
|
||||
div#info {
|
||||
max-width: 100%;
|
||||
margin-bottom: 20px;
|
||||
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
div#log {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
div.msg {
|
||||
display: flex;
|
||||
|
||||
margin-right: 10px;
|
||||
margin-left: 10px;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
div.msg-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
img.msg-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
div.msg-body {
|
||||
margin-left: 20px;
|
||||
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
span.msg-user {
|
||||
font-size: 1rem;
|
||||
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
span.msg-date {
|
||||
font-size: .75rem;
|
||||
|
||||
margin-left: 5px;
|
||||
|
||||
color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
span.msg-edited {
|
||||
font-size: .8rem;
|
||||
|
||||
margin-left: 5px;
|
||||
|
||||
color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
div.msg-content {
|
||||
font-size: .9375rem;
|
||||
|
||||
padding-top: 5px;
|
||||
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
div.msg-attachment {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
img.msg-attachment {
|
||||
max-width: 50%;
|
||||
max-height: 500px;
|
||||
}
|
105
DiscordChatExporter/Resources/HtmlExportService/LightTheme.css
Normal file
105
DiscordChatExporter/Resources/HtmlExportService/LightTheme.css
Normal file
|
@ -0,0 +1,105 @@
|
|||
body {
|
||||
font-family: Whitney, Helvetica Neue, Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
|
||||
color: #00B0F4;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.pre, span.pre {
|
||||
font-family: Consolas, Courier New, Courier, Monospace;
|
||||
|
||||
padding-right: 2px;
|
||||
padding-left: 2px;
|
||||
|
||||
background-color: #F9F9F9;
|
||||
}
|
||||
|
||||
div#info {
|
||||
max-width: 100%;
|
||||
margin-bottom: 20px;
|
||||
|
||||
color: #737F8D;
|
||||
}
|
||||
|
||||
div#log {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
div.msg {
|
||||
display: flex;
|
||||
|
||||
margin-right: 10px;
|
||||
margin-left: 10px;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
|
||||
border-top: 1px solid #ECEEEF;
|
||||
}
|
||||
|
||||
div.msg-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
img.msg-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
div.msg-body {
|
||||
margin-left: 20px;
|
||||
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
span.msg-user {
|
||||
font-size: 1rem;
|
||||
|
||||
color: #2F3136;
|
||||
}
|
||||
|
||||
span.msg-date {
|
||||
font-size: .75rem;
|
||||
|
||||
margin-left: 5px;
|
||||
|
||||
color: #99AAB5;
|
||||
}
|
||||
|
||||
span.msg-edited {
|
||||
font-size: .8rem;
|
||||
|
||||
margin-left: 5px;
|
||||
|
||||
color: #99AAB5;
|
||||
}
|
||||
|
||||
div.msg-content {
|
||||
font-size: .9375rem;
|
||||
|
||||
padding-top: 5px;
|
||||
|
||||
color: #737F8D;
|
||||
}
|
||||
|
||||
div.msg-attachment {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
img.msg-attachment {
|
||||
max-width: 50%;
|
||||
max-height: 500px;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<!-- This chat log was automatically generated by DiscordChatExporter (https://github.com/Tyrrrz/DiscordChatExporter) -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Discord Chat Log</title>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style id="theme">
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="info"></div>
|
||||
<div id="log"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,122 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Discord Chat Log</title>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
body {
|
||||
font-family: Whitney, Helvetica Neue, Helvetica, Arial, sans-serif;
|
||||
font-size: 15px;
|
||||
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
|
||||
color: #37bcf7;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.pre, span.pre {
|
||||
font-family: Consolas, Courier New, Courier, Monospace;
|
||||
|
||||
padding-right: 2px;
|
||||
padding-left: 2px;
|
||||
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
div#info {
|
||||
max-width: 100%;
|
||||
margin-bottom: 20px;
|
||||
|
||||
color: #939799;
|
||||
}
|
||||
|
||||
div#log {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
div.msg {
|
||||
display: flex;
|
||||
|
||||
margin-right: 10px;
|
||||
margin-left: 10px;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
|
||||
border-top: 1px solid #eceeef;
|
||||
}
|
||||
|
||||
div.msg-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
img.msg-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
div.msg-body {
|
||||
margin-left: 15px;
|
||||
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
span.msg-user {
|
||||
font-size: 1.15em;
|
||||
|
||||
color: #2f3136;
|
||||
}
|
||||
|
||||
span.msg-date {
|
||||
font-size: .8em;
|
||||
font-weight: 200;
|
||||
|
||||
margin-left: 5px;
|
||||
|
||||
color: #b7bcbf;
|
||||
}
|
||||
|
||||
span.msg-edited {
|
||||
font-size: .8em;
|
||||
font-weight: 200;
|
||||
|
||||
margin-left: 5px;
|
||||
|
||||
color: #b7bcbf;
|
||||
}
|
||||
|
||||
div.msg-content {
|
||||
padding-top: 5px;
|
||||
|
||||
color: #939799;
|
||||
}
|
||||
|
||||
div.msg-attachment {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
img.msg-attachment {
|
||||
max-width: 50%;
|
||||
max-height: 500px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="info"></div>
|
||||
<div id="log"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +1,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Text.RegularExpressions;
|
||||
using DiscordChatExporter.Models;
|
||||
using HtmlAgilityPack;
|
||||
|
@ -8,13 +10,18 @@ using Tyrrrz.Extensions;
|
|||
|
||||
namespace DiscordChatExporter.Services
|
||||
{
|
||||
public class ExportService
|
||||
public class HtmlExportService
|
||||
{
|
||||
private HtmlDocument GetTemplate()
|
||||
{
|
||||
const string templateName = "DiscordChatExporter.Services.ExportTemplate.html";
|
||||
string templateName = "DiscordChatExporter.Resources.HtmlExportService.Template.html";
|
||||
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
using (var stream = assembly.GetManifestResourceStream(templateName))
|
||||
var stream = assembly.GetManifestResourceStream(templateName);
|
||||
if (stream == null)
|
||||
throw new MissingManifestResourceException("Could not find template resource");
|
||||
|
||||
using (stream)
|
||||
{
|
||||
var doc = new HtmlDocument();
|
||||
doc.Load(stream);
|
||||
|
@ -22,6 +29,22 @@ namespace DiscordChatExporter.Services
|
|||
}
|
||||
}
|
||||
|
||||
private string GetStyle(Theme theme)
|
||||
{
|
||||
string styleName = $"DiscordChatExporter.Resources.HtmlExportService.{theme}Theme.css";
|
||||
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
var stream = assembly.GetManifestResourceStream(styleName);
|
||||
if (stream == null)
|
||||
throw new MissingManifestResourceException("Could not find theme style resource");
|
||||
|
||||
using (stream)
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<MessageGroup> GroupMessages(IEnumerable<Message> messages)
|
||||
{
|
||||
var result = new List<MessageGroup>();
|
||||
|
@ -99,9 +122,14 @@ namespace DiscordChatExporter.Services
|
|||
return content;
|
||||
}
|
||||
|
||||
public void Export(string filePath, ChatLog chatLog)
|
||||
public void Export(string filePath, ChatLog chatLog, Theme theme)
|
||||
{
|
||||
var doc = GetTemplate();
|
||||
string style = GetStyle(theme);
|
||||
|
||||
// Set theme
|
||||
var themeHtml = doc.GetElementbyId("theme");
|
||||
themeHtml.InnerHtml = style;
|
||||
|
||||
// Info
|
||||
var infoHtml = doc.GetElementbyId("info");
|
12
Readme.md
12
Readme.md
|
@ -12,7 +12,7 @@ Command line executable that can export [Discord](https://discordapp.com) channe
|
|||
|
||||
## Features
|
||||
|
||||
- Produces output styled similar to the Discord's light theme
|
||||
- Supports both dark and light theme
|
||||
- Displays user avatars
|
||||
- Groups messages by author and time
|
||||
- Handles Discord markdown characters
|
||||
|
@ -23,18 +23,18 @@ Command line executable that can export [Discord](https://discordapp.com) channe
|
|||
|
||||
## Usage
|
||||
|
||||
The program expects an access token and channel ID as parameters.
|
||||
The program expects an access token and channel ID as parameters. At minimum, the execution should look like this:
|
||||
|
||||
`DiscordChatExporter.exe /token:REkOTVqm9RWOTNOLCdiuMpWd.QiglBz.Lub0E0TZ1xX4ZxCtnwtpBhWt3v1 /channelId:459360869055190534`
|
||||
|
||||
#### Getting access token:
|
||||
#### Getting access token
|
||||
|
||||
- Open Discord desktop or web client
|
||||
- Press `Ctrl+Shift+I`
|
||||
- Navigate to `Application > Storage > Local Storage > https://discordapp.com`
|
||||
- Find the value for `token` and extract it
|
||||
|
||||
#### Getting channel ID:
|
||||
#### Getting channel ID
|
||||
|
||||
- Open Discord desktop or web client
|
||||
- Navigate to any DM or server channel
|
||||
|
@ -46,6 +46,10 @@ The program expects an access token and channel ID as parameters.
|
|||
- If it's a server channel, the format looks like this:
|
||||
`https://discordapp.com/channels/WHATEVER/CHANNEL_ID`
|
||||
|
||||
#### Optional arguments
|
||||
|
||||
- `/theme:[Dark/Light]` - sets the style of the output
|
||||
|
||||
## Libraries used
|
||||
|
||||
- [HtmlAgilityPack](https://github.com/zzzprojects/html-agility-pack)
|
||||
|
|
Loading…
Reference in a new issue