Skip to content

Commit

Permalink
feat: add renderer to be able to customize the output
Browse files Browse the repository at this point in the history
Closes #3
  • Loading branch information
sascha-andres committed Aug 24, 2020
1 parent 3b19fe7 commit eb24b70
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 87 deletions.
12 changes: 12 additions & 0 deletions .idea/.idea.MailDiary/.idea/contentModel.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

127 changes: 72 additions & 55 deletions .idea/.idea.MailDiary/.idea/workspace.xml

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion MailDiary.Filesystem/FilesystemHandler.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace MailDiary.Filesystem
{
using System.IO;
using Renderer;
using Types.Configuration;
using Types.Mail;

Expand All @@ -9,6 +10,7 @@ public class FilesystemHandler
private const string _FolderPattern = "yyyy/MM/dd";
private const string _FileNamePattern = "HHmmss";
private readonly Configuration _configuration;
private readonly Renderer _renderer;

/// <summary>
/// Constructor taking the configuration to handle writes to the storage
Expand All @@ -17,6 +19,7 @@ public class FilesystemHandler
public FilesystemHandler( Configuration config )
{
_configuration = config;
_renderer = new Renderer( _configuration );
}

/// <summary>
Expand All @@ -33,7 +36,7 @@ public void Save( MailMessage message )

var filename = message.Data.Received.ToString( _FileNamePattern ) + ".md";
File.WriteAllText( Path.Combine( completeFolder, filename ),
message.Data.ToMarkdown( _configuration.Processing.DateTimeFormat ) );
_renderer.Render( message ) );
}
}
}
1 change: 1 addition & 0 deletions MailDiary.Filesystem/MailDiary.Filesystem.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\MailDiary.Renderer\MailDiary.Renderer.csproj" />
<ProjectReference Include="..\MailDiary.Types\MailDiary.Types.csproj" />
</ItemGroup>

Expand Down
15 changes: 15 additions & 0 deletions MailDiary.Renderer/MailDiary.Renderer.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Scriban" Version="2.1.4" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MailDiary.Types\MailDiary.Types.csproj" />
</ItemGroup>

</Project>
48 changes: 48 additions & 0 deletions MailDiary.Renderer/Renderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
namespace MailDiary.Renderer
{
using System;
using System.ComponentModel;
using Scriban;
using Types.Configuration;
using Types.Mail;

/// <summary>
/// Used to create a text (markdown) representation of a message
/// </summary>
public class Renderer
{
private readonly Template _template;
private readonly Configuration _configuration;

/// <summary>
/// Constructor used to set things up
/// </summary>
/// <param name="configuration"></param>
public Renderer( Configuration configuration )
{
_configuration = configuration;
_template = Template.Parse( configuration.Processing.Template );
}

/// <summary>
/// Render one message
/// </summary>
/// <param name="message">Generate string from content of this message</param>
/// <returns>Rendered text</returns>
/// <exception cref="InvalidEnumArgumentException"></exception>
public string Render( MailMessage message )
{
if ( null == message ) throw new InvalidEnumArgumentException( "message may not be null" );
if ( string.IsNullOrEmpty( message.Data.Subject ) )
throw new InvalidOperationException( "Subject may not be empty" );
if ( string.IsNullOrEmpty( message.Data.Content ) )
throw new InvalidOperationException( "Content may not be empty" );
return _template.Render( new {
message.Data.Subject,
message.Data.Content,
Received =
message.Data.Received.ToString( _configuration.Processing.DateTimeFormat )
} );
}
}
}
6 changes: 6 additions & 0 deletions MailDiary.Types/Configuration/Processing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace MailDiary.Types.Configuration
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualBasic;
using YamlDotNet.Serialization;

/// <summary>
Expand All @@ -23,11 +24,16 @@ public class Processing

[YamlMember( Alias = "date-time-format", ApplyNamingConventions = false )]
public string DateTimeFormat { get; set; }
[YamlMember( Alias = "template", ApplyNamingConventions = false )]
public string Template { get; set; }

public Processing()
{
WhitelistedSenders = new List<string>();
DateTimeFormat = "dd/MM/yyyy HH:mm:ss";
Template = @"## ({{received}}) {{subject}}
{{content}}";
}

/// <summary>
Expand Down
23 changes: 0 additions & 23 deletions MailDiary.Types/Content/Incoming.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,8 @@ namespace MailDiary.Types.Content

public class Incoming
{
private const string MarkDownTemplate = @"## (%%RECEIVED%%) %%SUBJECT%%
%%CONTENT%%";

public DateTime Received { get; set; }
public string Subject { get; set; }
public string Content { get; set; }

/// <summary>
/// Generate markdown from data
/// </summary>
/// <param name="formatString">Used to format the datetime</param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public string ToMarkdown( string formatString )
{
if ( string.IsNullOrEmpty( Subject ) )
throw new InvalidOperationException( "Subject may not be empty" );
if ( string.IsNullOrEmpty( Content ) )
throw new InvalidOperationException( "Content may not be empty" );

return MarkDownTemplate
.Replace( "%%RECEIVED%%", Received.ToString( formatString ) )
.Replace( "%%SUBJECT%%", Subject )
.Replace( "%%CONTENT%%", Content );
}
}
}
7 changes: 7 additions & 0 deletions MailDiary.sln
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MailDiary.ImapConnector", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MailDiary.Filesystem", "MailDiary.Filesystem\MailDiary.Filesystem.csproj", "{200F045B-A479-4A88-A6C0-41BC0A8A0434}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MailDiary.Renderer", "MailDiary.Renderer\MailDiary.Renderer.csproj", "{877F3EEF-F916-49CC-91E3-EFF3343436FD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -40,11 +42,16 @@ Global
{200F045B-A479-4A88-A6C0-41BC0A8A0434}.Debug|Any CPU.Build.0 = Debug|Any CPU
{200F045B-A479-4A88-A6C0-41BC0A8A0434}.Release|Any CPU.ActiveCfg = Release|Any CPU
{200F045B-A479-4A88-A6C0-41BC0A8A0434}.Release|Any CPU.Build.0 = Release|Any CPU
{877F3EEF-F916-49CC-91E3-EFF3343436FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{877F3EEF-F916-49CC-91E3-EFF3343436FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{877F3EEF-F916-49CC-91E3-EFF3343436FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{877F3EEF-F916-49CC-91E3-EFF3343436FD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{7DAD7264-A53D-4C91-B910-DB38242B62DD} = {E3AAC9C7-DEBF-4CEB-8659-159A64F9A5B8}
{B40B243F-5B31-47E9-AF6B-AF1C6F48EFFC} = {4CB84535-1933-4B89-A8B8-BEC0CED5C5B2}
{C2058027-1F91-4930-B721-858CC76E8A0F} = {E3AAC9C7-DEBF-4CEB-8659-159A64F9A5B8}
{200F045B-A479-4A88-A6C0-41BC0A8A0434} = {E3AAC9C7-DEBF-4CEB-8659-159A64F9A5B8}
{877F3EEF-F916-49CC-91E3-EFF3343436FD} = {E3AAC9C7-DEBF-4CEB-8659-159A64F9A5B8}
EndGlobalSection
EndGlobal
25 changes: 18 additions & 7 deletions MailDiaryTypes.Tests/Content/IncomingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ namespace MailDiaryTypes.Tests.Content
{
using System;
using System.Globalization;
using MailDiary.Renderer;
using MailDiary.Types.Configuration;
using MailDiary.Types.Content;
using MailDiary.Types.Mail;
using Xunit;
using Xunit.Abstractions;

Expand All @@ -27,19 +30,27 @@ public IncomingTests( ITestOutputHelper testOutputHelper )
content" )]
[InlineData( "01/12/2000 01:01:01", "", "", true, @"## (01/12/2000 01:01:01) subject
content" )]
[InlineData( "01/12/2000 01:01:01", "subject", "", true, @"## (01/12/2000 01:01:01) subject
content" )]
public void MarkdownGenerationTests( string received, string subject, string content, bool hasException,
string expectedMarkdown )
{
var incoming = new Incoming {
Content = content, Received = DateTime.ParseExact( received, "dd/MM/yyyy HH:mm:ss",
CultureInfo.InvariantCulture ),
Subject = subject
};
var msg = new MailMessage();
msg.Data.Content = content;
msg.Data.Received = DateTime.ParseExact( received, "dd/MM/yyyy HH:mm:ss",
CultureInfo.InvariantCulture );
msg.Data.Subject = subject;

var renderer = new Renderer( new Configuration
{ Processing = new Processing { DateTimeFormat = "dd/MM/yyyy HH:mm:ss" } } );

var exceptionThrown = false;
var markdown = "";

var markdown = "";
try {
markdown = incoming.ToMarkdown("dd/MM/yyyy HH:mm:ss");
markdown = renderer.Render( msg );
} catch ( Exception ex ) {
_testOutputHelper.WriteLine( ex.Message );
exceptionThrown = true;
Expand Down
1 change: 1 addition & 0 deletions MailDiaryTypes.Tests/MailDiaryTypes.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MailDiary.Renderer\MailDiary.Renderer.csproj" />
<ProjectReference Include="..\MailDiary.Types\MailDiary.Types.csproj" />
</ItemGroup>

Expand Down
40 changes: 39 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,42 @@
# MailDiary

is a small tool to allow writing a diary by sending mails to another mail. The programs reads out the mails
and creates chunks of Markdown files. Those can then in turn be concatenated with mdmerge or shell magic.
and creates chunks of Markdown files. Those can then in turn be concatenated with mdmerge or shell magic.

## Configuration example

---

markdown-base-path: "c:/tools/maildiary"

mail:
server: "imap.some-server.de"
port: 993
user: super-secret-user
password: even-more-secret-password

processing:
whitelisted-senders:
- [email protected]
- [email protected]
- [email protected]
- [email protected]
date-time-format: "dd.MM.yyyy HH:mm:ss"
template: |
## ({{received}}) {{subject}}
{{content}}

The configuration sample will have MailDiary to connect to imap.some-server.de using IMAP and iterate over all mails. Foreach mail that was sent from one of the whitelisted senders it will generate a markdown file using the template provided (defaulting to the above one).

As a templating language this tool uses [scriban](https://github.com/lunet-io/scriban). For informatino about built in functions and how to use it read the documentation of scriban.

The markdown file will be named after hour, minute and second of the time when the mail was received and stored in a subfolder `year/month/day` in `markdown-base-path`.

Concatenation of generated markdown files is by design not part of this tool.

## History

|Version|Description|
|---|---|
|1.0.0.0|Initial version|

0 comments on commit eb24b70

Please sign in to comment.