Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into dev/robgruen/android_sans_…
Browse files Browse the repository at this point in the history
…MSAL
  • Loading branch information
robgruen committed Nov 13, 2024
2 parents 220ff29 + 6577d89 commit 392e416
Show file tree
Hide file tree
Showing 92 changed files with 2,260 additions and 980 deletions.
136 changes: 136 additions & 0 deletions dotnet/email/App.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Diagnostics;
using TypeAgent.Core;

namespace TypeAgent;

public class App
{
RootCommand _commands;
EmailExporter _exporter;
MailStats _stats;

public App(Outlook outlook)
{
_exporter = new EmailExporter(outlook);
_stats = new MailStats(outlook);

_commands = new RootCommand("Mail commands");
_commands.AddCommand(Command_Quit());
_commands.AddCommand(Command_Distribution());
_commands.AddCommand(Command_ExportAll());
}

public EmailExporter Exporter => _exporter;

public Command Command_Distribution()
{
Command command = new Command("distribution");
var pathOption = new Option<string>("--outPath", "Output path");
command.AddOption(pathOption);
command.SetHandler<string>((string outPath) =>
{
var (counter, histogram) = _stats.GetSizeDistribution();
ConsoleEx.WriteLineColor(ConsoleColor.Green, $"{counter} items");
string csv = MailStats.PrintHistogram(histogram);
if (!string.IsNullOrEmpty(outPath))
{
File.WriteAllText(outPath, csv);
}
Console.WriteLine(csv);
}, pathOption);
return command;
}

public Command Command_ExportAll()
{
Command command = new Command("exportAll");
var dirPath = new Option<string>("--destDir", "Output path");
var maxMessages = new Option<int>("--maxMessages", () => -1, "Max messages to export");
var bucket = new Option<bool>("--bucket", () => true, "Bucket messages by latest body size");
var includeJson = new Option<bool>("--includeJson", () => true, "Also export to Json");
command.AddOption(dirPath);
command.AddOption(maxMessages);
command.AddOption(bucket);
command.AddOption(includeJson);
command.SetHandler<string, int, bool, bool>((string dirPath, int maxMessages, bool bucket, bool includeJson) =>
{
_exporter.ExportAll(dirPath, maxMessages, bucket, includeJson);

}, dirPath, maxMessages, bucket, includeJson);

return command;
}

Command Command_Quit()
{
Command cmd = new Command("quit");
cmd.SetHandler(() => Environment.Exit(0));
return cmd;
}

static void Main(string[] args)
{
Console.OutputEncoding = Encoding.UTF8;
args = EnsureArgs(args);
if (args == null || args.Length == 0)
{
return;
}
try
{
using Outlook outlook = new Outlook();
var app = new App(outlook);
switch (args[0])
{
default:
if (args[0].StartsWith('@'))
{
RunInteractive(app, args);
}
else
{
app.Exporter.Export(args.ElementAtOrDefault(0), args.ElementAtOrDefault(1));
}
break;

case "--sender":
app.Exporter.ExportFrom(args.GetArg(1));
break;

case "--print":
app.Exporter.PrintEmail(args.GetArg(1));
Console.ReadLine();
return;
}
}
catch (System.Exception ex)
{
ConsoleEx.LogError(ex);
}
finally
{
COMObject.ReleaseAll();
}
}

static void RunInteractive(App app, string[] args)
{
while (true)
{
if (args.Length > 0)
{
args[0] = args[0][1..];
var result = app._commands.Invoke(args);
Console.WriteLine(result);
}
args = ConsoleEx.GetInput("📬>");
}
}

static string[]? EnsureArgs(string[] args)
{
return args != null && args.Length > 0 ? args : ConsoleEx.GetInput("📬>");
}
}
6 changes: 4 additions & 2 deletions dotnet/email/BodyParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ public BodyParser()

public string GetLatest(string body)
{
ArgumentException.ThrowIfNullOrEmpty(body);

if (string.IsNullOrEmpty(body))
{
return string.Empty;
}
int firstDelimiterAt = -1;
foreach (var delimiter in _delimiters)
{
Expand Down
8 changes: 8 additions & 0 deletions dotnet/email/COMObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ public static void Release(object value)
}
}

public static void Release(IEnumerable<object> values)
{
foreach (object value in values)
{
Release(value);
}
}

public static void ReleaseAll()
{
GC.Collect();
Expand Down
41 changes: 41 additions & 0 deletions dotnet/email/Core/ConsoleEx.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

namespace TypeAgent.Core;

public static class ConsoleEx
{
public static string[] GetInput(string prompt)
{
prompt ??= ">";
string line;
while (true)
{
Console.Write(prompt);
line = Console.ReadLine();
if (line != null)
{
line = line.Trim();
}
if (!string.IsNullOrEmpty(line))
{
return line.ParseCommandLine();
}
}
}

public static void LogError(System.Exception ex)
{
WriteLineColor(ConsoleColor.DarkYellow, $"##Error##\n{ex.Message}\n####");
Console.WriteLine();
}

public static void WriteLineColor(ConsoleColor color, string message)
{
var prevColor = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.WriteLine(message);
Console.ForegroundColor = prevColor;
}

}
40 changes: 40 additions & 0 deletions dotnet/email/Core/FileEx.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

namespace TypeAgent.Core;

public static class FileEx
{
public static string MakeUnique(string rootPath, string fileName, string ext)
{
string filePath = Path.Join(rootPath, fileName + ext);
int count = 0;
while (File.Exists(filePath))
{
++count;
string uniqueName = $"{fileName} ({count}){ext}";
filePath = Path.Join(rootPath, uniqueName);
}
return filePath;
}

public static string SanitizeFileName(string fileName, int maxLength = -1)
{
if (maxLength > 0 && fileName.Length > maxLength)
{
fileName = fileName[..maxLength];
}

char[] invalidChars = Path.GetInvalidFileNameChars();
StringBuilder sanitizedFileName = new StringBuilder();
foreach (char ch in fileName)
{
if (Array.IndexOf(invalidChars, ch) == -1)
{
sanitizedFileName.Append(ch);
}
}

return sanitizedFileName.ToString();
}
}
Loading

0 comments on commit 392e416

Please sign in to comment.