Use nullable

This commit is contained in:
Alexey Golub
2019-11-13 19:19:36 +02:00
parent 1bf9d9e2e2
commit e5a2852165
42 changed files with 195 additions and 196 deletions

View File

@@ -12,10 +12,10 @@ namespace DiscordChatExporter.Core.Services
{
private User ParseUser(JToken json)
{
var id = json["id"].Value<string>();
var discriminator = json["discriminator"].Value<int>();
var name = json["username"].Value<string>();
var avatarHash = json["avatar"].Value<string>();
var id = json["id"]!.Value<string>();
var discriminator = json["discriminator"]!.Value<int>();
var name = json["username"]!.Value<string>();
var avatarHash = json["avatar"]!.Value<string>();
var isBot = json["bot"]?.Value<bool>() ?? false;
return new User(id, discriminator, name, avatarHash, isBot);
@@ -23,9 +23,9 @@ namespace DiscordChatExporter.Core.Services
private Guild ParseGuild(JToken json)
{
var id = json["id"].Value<string>();
var name = json["name"].Value<string>();
var iconHash = json["icon"].Value<string>();
var id = json["id"]!.Value<string>();
var name = json["name"]!.Value<string>();
var iconHash = json["icon"]!.Value<string>();
return new Guild(id, name, iconHash);
}
@@ -33,23 +33,23 @@ namespace DiscordChatExporter.Core.Services
private Channel ParseChannel(JToken json)
{
// Get basic data
var id = json["id"].Value<string>();
var id = json["id"]!.Value<string>();
var parentId = json["parent_id"]?.Value<string>();
var type = (ChannelType) json["type"].Value<int>();
var type = (ChannelType) json["type"]!.Value<int>();
var topic = json["topic"]?.Value<string>();
// Try to extract guild ID
var guildId = json["guild_id"]?.Value<string>();
// If the guild ID is blank, it's direct messages
if (guildId.IsNullOrWhiteSpace())
if (string.IsNullOrWhiteSpace(guildId))
guildId = Guild.DirectMessages.Id;
// Try to extract name
var name = json["name"]?.Value<string>();
// If the name is blank, it's direct messages
if (name.IsNullOrWhiteSpace())
if (string.IsNullOrWhiteSpace(name))
name = json["recipients"].Select(ParseUser).Select(u => u.Name).JoinToString(", ");
return new Channel(id, parentId, guildId, name, topic, type);
@@ -57,20 +57,20 @@ namespace DiscordChatExporter.Core.Services
private Role ParseRole(JToken json)
{
var id = json["id"].Value<string>();
var name = json["name"].Value<string>();
var id = json["id"]!.Value<string>();
var name = json["name"]!.Value<string>();
return new Role(id, name);
}
private Attachment ParseAttachment(JToken json)
{
var id = json["id"].Value<string>();
var url = json["url"].Value<string>();
var id = json["id"]!.Value<string>();
var url = json["url"]!.Value<string>();
var width = json["width"]?.Value<int>();
var height = json["height"]?.Value<int>();
var fileName = json["filename"].Value<string>();
var fileSizeBytes = json["size"].Value<long>();
var fileName = json["filename"]!.Value<string>();
var fileSizeBytes = json["size"]!.Value<long>();
var fileSize = new FileSize(fileSizeBytes);
@@ -88,8 +88,8 @@ namespace DiscordChatExporter.Core.Services
private EmbedField ParseEmbedField(JToken json)
{
var name = json["name"].Value<string>();
var value = json["value"].Value<string>();
var name = json["name"]!.Value<string>();
var value = json["value"]!.Value<string>();
var isInline = json["inline"]?.Value<bool>() ?? false;
return new EmbedField(name, value, isInline);
@@ -106,7 +106,7 @@ namespace DiscordChatExporter.Core.Services
private EmbedFooter ParseEmbedFooter(JToken json)
{
var text = json["text"].Value<string>();
var text = json["text"]!.Value<string>();
var iconUrl = json["icon_url"]?.Value<string>();
return new EmbedFooter(text, iconUrl);
@@ -122,23 +122,23 @@ namespace DiscordChatExporter.Core.Services
// Get color
var color = json["color"] != null
? Color.FromArgb(json["color"].Value<int>()).ResetAlpha()
? Color.FromArgb(json["color"]!.Value<int>()).ResetAlpha()
: Color.FromArgb(79, 84, 92); // default color
// Get author
var author = json["author"] != null ? ParseEmbedAuthor(json["author"]) : null;
var author = json["author"] != null ? ParseEmbedAuthor(json["author"]!) : null;
// Get fields
var fields = json["fields"].EmptyIfNull().Select(ParseEmbedField).ToArray();
var fields = (json["fields"] ?? Enumerable.Empty<JToken>()).Select(ParseEmbedField).ToArray();
// Get thumbnail
var thumbnail = json["thumbnail"] != null ? ParseEmbedImage(json["thumbnail"]) : null;
var thumbnail = json["thumbnail"] != null ? ParseEmbedImage(json["thumbnail"]!) : null;
// Get image
var image = json["image"] != null ? ParseEmbedImage(json["image"]) : null;
var image = json["image"] != null ? ParseEmbedImage(json["image"]!) : null;
// Get footer
var footer = json["footer"] != null ? ParseEmbedFooter(json["footer"]) : null;
var footer = json["footer"] != null ? ParseEmbedFooter(json["footer"]!) : null;
return new Embed(title, url, timestamp, color, author, description, fields, thumbnail, image, footer);
}
@@ -146,7 +146,7 @@ namespace DiscordChatExporter.Core.Services
private Emoji ParseEmoji(JToken json)
{
var id = json["id"]?.Value<string>();
var name = json["name"]?.Value<string>();
var name = json["name"]!.Value<string>();
var isAnimated = json["animated"]?.Value<bool>() ?? false;
return new Emoji(id, name, isAnimated);
@@ -154,8 +154,8 @@ namespace DiscordChatExporter.Core.Services
private Reaction ParseReaction(JToken json)
{
var count = json["count"].Value<int>();
var emoji = ParseEmoji(json["emoji"]);
var count = json["count"]!.Value<int>();
var emoji = ParseEmoji(json["emoji"]!);
return new Reaction(count, emoji);
}
@@ -163,12 +163,12 @@ namespace DiscordChatExporter.Core.Services
private Message ParseMessage(JToken json)
{
// Get basic data
var id = json["id"].Value<string>();
var channelId = json["channel_id"].Value<string>();
var timestamp = json["timestamp"].Value<DateTime>().ToDateTimeOffset();
var id = json["id"]!.Value<string>();
var channelId = json["channel_id"]!.Value<string>();
var timestamp = json["timestamp"]!.Value<DateTime>().ToDateTimeOffset();
var editedTimestamp = json["edited_timestamp"]?.Value<DateTime?>()?.ToDateTimeOffset();
var content = json["content"].Value<string>();
var type = (MessageType) json["type"].Value<int>();
var content = json["content"]!.Value<string>();
var type = (MessageType) json["type"]!.Value<int>();
// Workarounds for non-default types
if (type == MessageType.RecipientAdd)
@@ -187,22 +187,22 @@ namespace DiscordChatExporter.Core.Services
content = "Joined the server.";
// Get author
var author = ParseUser(json["author"]);
var author = ParseUser(json["author"]!);
// Get attachments
var attachments = json["attachments"].EmptyIfNull().Select(ParseAttachment).ToArray();
var attachments = (json["attachments"] ?? Enumerable.Empty<JToken>()).Select(ParseAttachment).ToArray();
// Get embeds
var embeds = json["embeds"].EmptyIfNull().Select(ParseEmbed).ToArray();
var embeds = (json["embeds"] ?? Enumerable.Empty<JToken>()).Select(ParseEmbed).ToArray();
// Get reactions
var reactions = json["reactions"].EmptyIfNull().Select(ParseReaction).ToArray();
var reactions = (json["reactions"] ?? Enumerable.Empty<JToken>()).Select(ParseReaction).ToArray();
// Get mentioned users
var mentionedUsers = json["mentions"].EmptyIfNull().Select(ParseUser).ToArray();
var mentionedUsers = (json["mentions"] ?? Enumerable.Empty<JToken>()).Select(ParseUser).ToArray();
// Get whether this message is pinned
var isPinned = json["pinned"].Value<bool>();
var isPinned = json["pinned"]!.Value<bool>();
return new Message(id, channelId, type, author, timestamp, editedTimestamp, content, attachments, embeds,
reactions, mentionedUsers, isPinned);

View File

@@ -45,7 +45,7 @@ namespace DiscordChatExporter.Core.Services
var value = parameter.SubstringAfter("=");
// Skip empty values
if (value.IsNullOrWhiteSpace())
if (string.IsNullOrWhiteSpace(value))
continue;
request.RequestUri = request.RequestUri.SetQueryParameter(key, value);
@@ -53,6 +53,7 @@ namespace DiscordChatExporter.Core.Services
// Get response
using var response = await _httpClient.SendAsync(request);
// Check status code
// We throw our own exception here because default one doesn't have status code
if (!response.IsSuccessStatusCode)
@@ -119,7 +120,7 @@ namespace DiscordChatExporter.Core.Services
}
public async Task<IReadOnlyList<Message>> GetChannelMessagesAsync(AuthToken token, string channelId,
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double> progress = null)
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double>? progress = null)
{
var result = new List<Message>();
@@ -211,7 +212,7 @@ namespace DiscordChatExporter.Core.Services
}
public async Task<ChatLog> GetChatLogAsync(AuthToken token, Guild guild, Channel channel,
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double> progress = null)
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double>? progress = null)
{
// Get messages
var messages = await GetChannelMessagesAsync(token, channel.Id, after, before, progress);
@@ -223,19 +224,19 @@ namespace DiscordChatExporter.Core.Services
}
public async Task<ChatLog> GetChatLogAsync(AuthToken token, Channel channel,
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double> progress = null)
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double>? progress = null)
{
// Get guild
var guild = channel.GuildId == Guild.DirectMessages.Id
? Guild.DirectMessages
: await GetGuildAsync(token, channel.GuildId);
var guild = !string.IsNullOrWhiteSpace(channel.GuildId)
? await GetGuildAsync(token, channel.GuildId)
: Guild.DirectMessages;
// Get the chat log
return await GetChatLogAsync(token, guild, channel, after, before, progress);
}
public async Task<ChatLog> GetChatLogAsync(AuthToken token, string channelId,
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double> progress = null)
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double>? progress = null)
{
// Get channel
var channel = await GetChannelAsync(token, channelId);

View File

@@ -2,13 +2,14 @@
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Failsafe" Version="1.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Onova" Version="2.4.5" />
<PackageReference Include="Tyrrrz.Extensions" Version="1.6.3" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Onova" Version="2.5.1" />
<PackageReference Include="Tyrrrz.Extensions" Version="1.6.5" />
<PackageReference Include="Tyrrrz.Settings" Version="1.3.4" />
</ItemGroup>

View File

@@ -38,7 +38,7 @@ namespace DiscordChatExporter.Core.Services
{
// Create output directory
var dirPath = Path.GetDirectoryName(filePath);
if (!dirPath.IsNullOrWhiteSpace())
if (!string.IsNullOrWhiteSpace(dirPath))
Directory.CreateDirectory(dirPath);
// Render chat log to output file
@@ -74,7 +74,7 @@ namespace DiscordChatExporter.Core.Services
var partitionFilePath = $"{fileNameWithoutExt} [{partitionNumber} of {partitions.Length}]{fileExt}";
// Compose full file path
if (!dirPath.IsNullOrWhiteSpace())
if (!string.IsNullOrWhiteSpace(dirPath))
partitionFilePath = Path.Combine(dirPath, partitionFilePath);
// Export

View File

@@ -3,7 +3,6 @@ using System.IO;
using System.Linq;
using System.Text;
using DiscordChatExporter.Core.Models;
using Tyrrrz.Extensions;
namespace DiscordChatExporter.Core.Services.Helpers
{
@@ -12,7 +11,7 @@ namespace DiscordChatExporter.Core.Services.Helpers
public static bool IsDirectoryPath(string path) =>
path.Last() == Path.DirectorySeparatorChar ||
path.Last() == Path.AltDirectorySeparatorChar ||
Path.GetExtension(path).IsNullOrWhiteSpace() && !File.Exists(path);
string.IsNullOrWhiteSpace(Path.GetExtension(path)) && !File.Exists(path);
public static string GetDefaultExportFileName(ExportFormat format, Guild guild, Channel channel,
DateTimeOffset? after = null, DateTimeOffset? before = null)

View File

@@ -9,8 +9,10 @@ namespace DiscordChatExporter.Core.Services
public string DateFormat { get; set; } = "dd-MMM-yy hh:mm tt";
public AuthToken LastToken { get; set; }
public AuthToken? LastToken { get; set; }
public ExportFormat LastExportFormat { get; set; } = ExportFormat.HtmlDark;
public int? LastPartitionLimit { get; set; }
public SettingsService()