Refactor resolving chat log to a separate service to allow reusability across CLI and GUI

This commit is contained in:
Alexey Golub 2018-10-30 22:52:28 +02:00
parent 4e8fb80ac5
commit 95a4217ab3
7 changed files with 81 additions and 40 deletions

View file

@ -12,6 +12,7 @@ namespace DiscordChatExporter.Cli
SimpleIoc.Default.Reset(); SimpleIoc.Default.Reset();
// Services // Services
SimpleIoc.Default.Register<IChatLogService, ChatLogService>();
SimpleIoc.Default.Register<IDataService, DataService>(); SimpleIoc.Default.Register<IDataService, DataService>();
SimpleIoc.Default.Register<IExportService, ExportService>(); SimpleIoc.Default.Register<IExportService, ExportService>();
SimpleIoc.Default.Register<IMessageGroupService, MessageGroupService>(); SimpleIoc.Default.Register<IMessageGroupService, MessageGroupService>();

View file

@ -20,8 +20,7 @@ namespace DiscordChatExporter.Cli.Verbs
// Get services // Get services
var container = new Container(); var container = new Container();
var settingsService = container.Resolve<ISettingsService>(); var settingsService = container.Resolve<ISettingsService>();
var dataService = container.Resolve<IDataService>(); var chatLogService = container.Resolve<IChatLogService>();
var messageGroupService = container.Resolve<IMessageGroupService>();
var exportService = container.Resolve<IExportService>(); var exportService = container.Resolve<IExportService>();
// Configure settings // Configure settings
@ -30,37 +29,20 @@ namespace DiscordChatExporter.Cli.Verbs
if (Options.MessageGroupLimit > 0) if (Options.MessageGroupLimit > 0)
settingsService.MessageGroupLimit = Options.MessageGroupLimit; settingsService.MessageGroupLimit = Options.MessageGroupLimit;
// Get channel and guild // Get chat log
var channel = await dataService.GetChannelAsync(Options.GetToken(), Options.ChannelId); var chatLog = await chatLogService.GetChatLogAsync(Options.GetToken(), Options.ChannelId,
var guild = channel.GuildId == Guild.DirectMessages.Id Options.After, Options.Before);
? Guild.DirectMessages
: await dataService.GetGuildAsync(Options.GetToken(), channel.GuildId);
// Generate file path if not set // Generate file path if not set
var filePath = Options.FilePath; var filePath = Options.FilePath;
if (filePath == null || filePath.EndsWith("/") || filePath.EndsWith("\\")) if (filePath == null || filePath.EndsWith("/") || filePath.EndsWith("\\"))
{ {
filePath += $"{guild.Name} - {channel.Name}.{Options.ExportFormat.GetFileExtension()}" filePath += $"{chatLog.Guild.Name} - {chatLog.Channel.Name}.{Options.ExportFormat.GetFileExtension()}"
.Replace(Path.GetInvalidFileNameChars(), '_'); .Replace(Path.GetInvalidFileNameChars(), '_');
} }
// TODO: extract this to make it reusable across implementations
// Get messages
var messages =
await dataService.GetChannelMessagesAsync(Options.GetToken(), channel.Id,
Options.After, Options.Before);
// Group messages
var messageGroups = messageGroupService.GroupMessages(messages);
// Get mentionables
var mentionables = await dataService.GetMentionablesAsync(Options.GetToken(), guild.Id, messages);
// Create log
var log = new ChatLog(guild, channel, Options.After, Options.Before, messageGroups, mentionables);
// Export // Export
exportService.Export(Options.ExportFormat, filePath, log); exportService.Export(Options.ExportFormat, filePath, chatLog);
// Print result // Print result
Console.WriteLine($"Exported chat to [{filePath}]"); Console.WriteLine($"Exported chat to [{filePath}]");

View file

@ -0,0 +1,48 @@
using System;
using System.Threading.Tasks;
using DiscordChatExporter.Core.Models;
namespace DiscordChatExporter.Core.Services
{
public class ChatLogService : IChatLogService
{
private readonly IDataService _dataService;
private readonly IMessageGroupService _messageGroupService;
public ChatLogService(IDataService dataService, IMessageGroupService messageGroupService)
{
_dataService = dataService;
_messageGroupService = messageGroupService;
}
public async Task<ChatLog> GetChatLogAsync(AuthToken token, Guild guild, Channel channel,
DateTime? from = null, DateTime? to = null, IProgress<double> progress = null)
{
// Get messages
var messages = await _dataService.GetChannelMessagesAsync(token, channel.Id, from, to, progress);
// Group messages
var messageGroups = _messageGroupService.GroupMessages(messages);
// Get mentionables
var mentionables = await _dataService.GetMentionablesAsync(token, guild.Id, messages);
return new ChatLog(guild, channel, from, to, messageGroups, mentionables);
}
public async Task<ChatLog> GetChatLogAsync(AuthToken token, string channelId,
DateTime? from = null, DateTime? to = null, IProgress<double> progress = null)
{
// Get channel
var channel = await _dataService.GetChannelAsync(token, channelId);
// Get guild
var guild = channel.GuildId == Guild.DirectMessages.Id
? Guild.DirectMessages
: await _dataService.GetGuildAsync(token, channel.GuildId);
// Get the chat log
return await GetChatLogAsync(token, guild, channel, from, to, progress);
}
}
}

View file

@ -65,6 +65,10 @@ namespace DiscordChatExporter.Core.Services
public async Task<Guild> GetGuildAsync(AuthToken token, string guildId) public async Task<Guild> GetGuildAsync(AuthToken token, string guildId)
{ {
// Special case for direct messages pseudo-guild
if (guildId == Guild.DirectMessages.Id)
return Guild.DirectMessages;
var response = await GetApiResponseAsync(token, "guilds", guildId); var response = await GetApiResponseAsync(token, "guilds", guildId);
var guild = ParseGuild(response); var guild = ParseGuild(response);

View file

@ -0,0 +1,15 @@
using System;
using System.Threading.Tasks;
using DiscordChatExporter.Core.Models;
namespace DiscordChatExporter.Core.Services
{
public interface IChatLogService
{
Task<ChatLog> GetChatLogAsync(AuthToken token, Guild guild, Channel channel,
DateTime? from = null, DateTime? to = null, IProgress<double> progress = null);
Task<ChatLog> GetChatLogAsync(AuthToken token, string channelId,
DateTime? from = null, DateTime? to = null, IProgress<double> progress = null);
}
}

View file

@ -17,6 +17,7 @@ namespace DiscordChatExporter.Gui
SimpleIoc.Default.Reset(); SimpleIoc.Default.Reset();
// Services // Services
SimpleIoc.Default.Register<IChatLogService, ChatLogService>();
SimpleIoc.Default.Register<IDataService, DataService>(); SimpleIoc.Default.Register<IDataService, DataService>();
SimpleIoc.Default.Register<IExportService, ExportService>(); SimpleIoc.Default.Register<IExportService, ExportService>();
SimpleIoc.Default.Register<IMessageGroupService, MessageGroupService>(); SimpleIoc.Default.Register<IMessageGroupService, MessageGroupService>();

View file

@ -19,7 +19,7 @@ namespace DiscordChatExporter.Gui.ViewModels
private readonly ISettingsService _settingsService; private readonly ISettingsService _settingsService;
private readonly IUpdateService _updateService; private readonly IUpdateService _updateService;
private readonly IDataService _dataService; private readonly IDataService _dataService;
private readonly IMessageGroupService _messageGroupService; private readonly IChatLogService _chatLogService;
private readonly IExportService _exportService; private readonly IExportService _exportService;
private readonly Dictionary<Guild, IReadOnlyList<Channel>> _guildChannelsMap; private readonly Dictionary<Guild, IReadOnlyList<Channel>> _guildChannelsMap;
@ -111,12 +111,12 @@ namespace DiscordChatExporter.Gui.ViewModels
public RelayCommand<Channel> ShowExportSetupCommand { get; } public RelayCommand<Channel> ShowExportSetupCommand { get; }
public MainViewModel(ISettingsService settingsService, IUpdateService updateService, IDataService dataService, public MainViewModel(ISettingsService settingsService, IUpdateService updateService, IDataService dataService,
IMessageGroupService messageGroupService, IExportService exportService) IChatLogService chatLogService, IExportService exportService)
{ {
_settingsService = settingsService; _settingsService = settingsService;
_updateService = updateService; _updateService = updateService;
_dataService = dataService; _dataService = dataService;
_messageGroupService = messageGroupService; _chatLogService = chatLogService;
_exportService = exportService; _exportService = exportService;
_guildChannelsMap = new Dictionary<Guild, IReadOnlyList<Channel>>(); _guildChannelsMap = new Dictionary<Guild, IReadOnlyList<Channel>>();
@ -256,21 +256,11 @@ namespace DiscordChatExporter.Gui.ViewModels
try try
{ {
// TODO: extract this to make it reusable across implementations // Get chat log
// Get messages var chatLog = await _chatLogService.GetChatLogAsync(token, guild, channel, from, to, progressHandler);
var messages = await _dataService.GetChannelMessagesAsync(token, channel.Id, from, to, progressHandler);
// Group messages
var messageGroups = _messageGroupService.GroupMessages(messages);
// Get mentionables
var mentionables = await _dataService.GetMentionablesAsync(token, guild.Id, messages);
// Create log
var log = new ChatLog(guild, channel, from, to, messageGroups, mentionables);
// Export // Export
_exportService.Export(format, filePath, log); _exportService.Export(format, filePath, chatLog);
// Open // Open
Process.Start(filePath); Process.Start(filePath);