diff --git a/EmailNodes/Communication/SendEmail.cs b/EmailNodes/Communication/SendEmail.cs new file mode 100644 index 00000000..4ac5ebfe --- /dev/null +++ b/EmailNodes/Communication/SendEmail.cs @@ -0,0 +1,90 @@ + +using MailKit.Net.Smtp; +using MimeKit; + +namespace FileFlows.Communication +{ + public class SendEmail:Node + { + public override int Inputs => 1; + public override int Outputs => 1; + public override string Icon => "fas fa-envelope"; + + public override FlowElementType Type => FlowElementType.Process; + + [StringArray(1)] + public string[] Recipients { get; set; } + + [TextVariable(2)] + public string Subject { get; set; } + + [TextArea(3)] + public string Body { get; set; } + + public override int Execute(NodeParameters args) + { + var settings = args.GetPluginSettings(); + + if (string.IsNullOrEmpty(settings?.SmtpServer)) + { + args.Logger?.ELog("No SMTP Server configured, configure this under the 'Plugins > Email Nodes > Edit' page."); + return -1; + } + string body = this.Body ?? string.Empty; + string sender = settings.Sender ?? "fileflows@" + Environment.MachineName; + string subject = args.ReplaceVariables(this.Subject ?? String.Empty)?.EmptyAsNull() ?? "Email from FileFlows"; ; + + var message = new MimeMessage(); + message.From.Add(new MailboxAddress(sender, sender)); + foreach (var recipient in Recipients) + message.To.Add(new MailboxAddress(recipient, recipient)); + message.Subject = subject; + message.Body = new TextPart("plain") + { + Text = body + }; + + using(var client = new SmtpClient()) + { + client.Connect(settings.SmtpServer, settings.SmtpPort); + + if (string.IsNullOrEmpty(settings.SmtpUsername) == false) + { + args.Logger?.ILog("Sending using credientials"); + client.AuthenticationMechanisms.Remove("XOAUTH2"); + client.Authenticate(settings.SmtpUsername, settings.SmtpPassword); + } + client.Send(message); + client.Disconnect(true); + } + + + + + + //MailMessage message = new MailMessage(); + //message.From = new MailAddress(sender); + //foreach (var recipient in Recipients) + // message.To.Add(recipient); + //message.Subject = subject; + //message.Body = args.ReplaceVariables(body); + + + + //SmtpClient smtp = new SmtpClient(); + //smtp.Port = settings.SmtpPort; + //smtp.Host = settings.SmtpServer; + //if (string.IsNullOrEmpty(settings.SmtpUsername) == false) + //{ + // args.Logger?.ILog("Sending using credientials"); + // smtp.EnableSsl = true; + // smtp.UseDefaultCredentials = false; + // smtp.Credentials = new NetworkCredential(settings.SmtpUsername, settings.SmtpPassword); + // //smtp.DeliveryMethod = SmtpDeliveryMethod.Network; + //} + //smtp.Send(message); + + return 1; + } + } +} diff --git a/EmailNodes/EmailNodes.csproj b/EmailNodes/EmailNodes.csproj new file mode 100644 index 00000000..8d2a846f Binary files /dev/null and b/EmailNodes/EmailNodes.csproj differ diff --git a/EmailNodes/EmailNodes.en.json b/EmailNodes/EmailNodes.en.json new file mode 100644 index 00000000..7ac92e91 --- /dev/null +++ b/EmailNodes/EmailNodes.en.json @@ -0,0 +1,34 @@ +{ + "Plugins": { + "EmailNodes": { + "Fields": { + "SmtpServer": "SMTP Server", + "SmtpServer-Help": "The address of the SMTP Server used to send emails", + "SmtpPort": "SMTP Port", + "SmtpPort-Help": "The port of the SMTP Server used to send emails, default 25", + "SmtpUsername": "SMTP Username", + "SmtpUsername-Help": "The username used to authenticate against the SMTP Server", + "SmtpPassword": "SMTP Password", + "SmtpPassword-Help": "The password used to authenticate against the SMTP Server" + } + } + }, + "Flow": { + "Parts": { + "SendEmail": { + "Outputs": { + "1": "Sent email to {Recipient}" + }, + "Description": "Sends an email using the configured SMTP Server", + "Fields": { + "Recipients": "Recipients", + "Recipients-Help": "A list of email addresses to send the message to", + "Subject": "Subject", + "Subject-Help": "The subject of the email being set", + "Body": "Body", + "Body-Help": "The content of the email message being sent. " + } + } + } + } +} \ No newline at end of file diff --git a/EmailNodes/ExtensionMethods.cs b/EmailNodes/ExtensionMethods.cs new file mode 100644 index 00000000..aae06014 --- /dev/null +++ b/EmailNodes/ExtensionMethods.cs @@ -0,0 +1,16 @@ +namespace FileFlows.EmailNodes +{ + internal static class ExtensionMethods + { + public static void AddOrUpdate(this Dictionary dict, string key, object value) { + if (dict.ContainsKey(key)) + dict[key] = value; + else + dict.Add(key, value); + } + public static string? EmptyAsNull(this string str) + { + return str == string.Empty ? null : str; + } + } +} diff --git a/EmailNodes/GlobalUsings.cs b/EmailNodes/GlobalUsings.cs new file mode 100644 index 00000000..ebde50b8 --- /dev/null +++ b/EmailNodes/GlobalUsings.cs @@ -0,0 +1,3 @@ +global using FileFlows.Plugin; +global using FileFlows.EmailNodes; +global using FileFlows.Plugin.Attributes; \ No newline at end of file diff --git a/EmailNodes/Plugin.cs b/EmailNodes/Plugin.cs new file mode 100644 index 00000000..b86909d1 --- /dev/null +++ b/EmailNodes/Plugin.cs @@ -0,0 +1,12 @@ +namespace FileFlows.EmailNodes +{ + public class Plugin : IPlugin + { + public string Name => "Email Nodes"; + public string MinimumVersion => "0.3.1.378"; + + public void Init() + { + } + } +} \ No newline at end of file diff --git a/EmailNodes/PluginSettings.cs b/EmailNodes/PluginSettings.cs new file mode 100644 index 00000000..f46771b1 --- /dev/null +++ b/EmailNodes/PluginSettings.cs @@ -0,0 +1,29 @@ +namespace FileFlows.EmailNodes +{ + using FileFlows.Plugin; + using FileFlows.Plugin.Attributes; + using System; + using System.ComponentModel.DataAnnotations; + + public class PluginSettings:IPluginSettings + { + [Required] + [Text(1)] + public string SmtpServer { get; set; } + + [Range(1, 6555)] + [NumberInt(1)] + public int SmtpPort { get; set; } + + [Text(2)] + public string SmtpUsername { get; set; } + + [Text(3)] + public string SmtpPassword { get; set; } + + [Text(4)] + [Required] + [System.ComponentModel.DataAnnotations.RegularExpression(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$")] + public string Sender { get; set; } + } +} diff --git a/build/utils/PluginInfoGenerator/FileFlows.Plugin.dll b/build/utils/PluginInfoGenerator/FileFlows.Plugin.dll index 3b12bf91..f26d50f7 100644 Binary files a/build/utils/PluginInfoGenerator/FileFlows.Plugin.dll and b/build/utils/PluginInfoGenerator/FileFlows.Plugin.dll differ diff --git a/build/utils/PluginInfoGenerator/FileFlows.Plugin.pdb b/build/utils/PluginInfoGenerator/FileFlows.Plugin.pdb index c5e9ba2d..9f97d6ec 100644 Binary files a/build/utils/PluginInfoGenerator/FileFlows.Plugin.pdb and b/build/utils/PluginInfoGenerator/FileFlows.Plugin.pdb differ diff --git a/build/utils/PluginInfoGenerator/FileFlows.ServerShared.dll b/build/utils/PluginInfoGenerator/FileFlows.ServerShared.dll index 2dcee545..0d4a3e5e 100644 Binary files a/build/utils/PluginInfoGenerator/FileFlows.ServerShared.dll and b/build/utils/PluginInfoGenerator/FileFlows.ServerShared.dll differ diff --git a/build/utils/PluginInfoGenerator/FileFlows.ServerShared.pdb b/build/utils/PluginInfoGenerator/FileFlows.ServerShared.pdb index 5f7e3f84..f7c1b92c 100644 Binary files a/build/utils/PluginInfoGenerator/FileFlows.ServerShared.pdb and b/build/utils/PluginInfoGenerator/FileFlows.ServerShared.pdb differ diff --git a/build/utils/PluginInfoGenerator/FileFlows.Shared.dll b/build/utils/PluginInfoGenerator/FileFlows.Shared.dll index 4553c842..e2c6824d 100644 Binary files a/build/utils/PluginInfoGenerator/FileFlows.Shared.dll and b/build/utils/PluginInfoGenerator/FileFlows.Shared.dll differ diff --git a/build/utils/PluginInfoGenerator/FileFlows.Shared.pdb b/build/utils/PluginInfoGenerator/FileFlows.Shared.pdb index bf17c94b..2a50006c 100644 Binary files a/build/utils/PluginInfoGenerator/FileFlows.Shared.pdb and b/build/utils/PluginInfoGenerator/FileFlows.Shared.pdb differ diff --git a/build/utils/PluginInfoGenerator/PluginInfoGenerator.dll b/build/utils/PluginInfoGenerator/PluginInfoGenerator.dll index 1ed6baec..2990132e 100644 Binary files a/build/utils/PluginInfoGenerator/PluginInfoGenerator.dll and b/build/utils/PluginInfoGenerator/PluginInfoGenerator.dll differ diff --git a/build/utils/PluginInfoGenerator/PluginInfoGenerator.pdb b/build/utils/PluginInfoGenerator/PluginInfoGenerator.pdb index 5b338db6..18c63efb 100644 Binary files a/build/utils/PluginInfoGenerator/PluginInfoGenerator.pdb and b/build/utils/PluginInfoGenerator/PluginInfoGenerator.pdb differ diff --git a/build/utils/spellcheck/ignoredwords.txt b/build/utils/spellcheck/ignoredwords.txt index 1cea7b76..6254ba8f 100644 --- a/build/utils/spellcheck/ignoredwords.txt +++ b/build/utils/spellcheck/ignoredwords.txt @@ -54,4 +54,5 @@ Kbps AAC WAV OGG -FLAC \ No newline at end of file +FLAC +SMTP \ No newline at end of file diff --git a/deploy/VideoNodes.ffplugin b/deploy/VideoNodes.ffplugin deleted file mode 100644 index 9f49b541..00000000 Binary files a/deploy/VideoNodes.ffplugin and /dev/null differ diff --git a/deploy/plugins.json b/deploy/plugins.json deleted file mode 100644 index 29a9a9a3..00000000 --- a/deploy/plugins.json +++ /dev/null @@ -1,99 +0,0 @@ -[ -{ - "Name": "Basic Nodes", - "Version": "0.0.1.80", - "MinimumVersion": "0.2.1.349", - "Authors": "John Andrews", - "Url": "https://fileflows.com/", - "Description": "Basic nodes for FileFlows. This plugin contains basic and common nodes to process files. \r\nThis plugin is required for FileFlows to work.", - "Package": "BasicNodes", - "Elements": [ - "InputFile", - "InputFolder", - "CopyFile", - "Delete", - "DeleteSourceDirectory", - "Executor", - "MoveFile", - "Renamer", - "ReplaceOriginal", - "Zip", - "FileExists", - "FileExtension", - "FileSize", - "Function", - "GotoFlow", - "Log", - "PatternMatch", - "PatternReplacer" - ] -}, -{ - "Name": "Checksum Nodes", - "Version": "0.0.1.80", - "MinimumVersion": "", - "Authors": "John Andrews", - "Url": "https://fileflows.com/", - "Description": "Nodes that provide the ability to run a checksum against a file.", - "Package": "ChecksumNodes", - "Elements": [ - "MD5", - "SHA1", - "SHA256", - "SHA512" - ] -}, -{ - "Name": "Collection Nodes", - "Version": "0.0.1.80", - "MinimumVersion": "0.2.0.310", - "Authors": "John Andrews", - "Url": "https://fileflows.com/", - "Description": "Nodes that provide the ability to read and write from collections.\r\n\r\nAllows storing of data to database that persists between flow executions.", - "Package": "CollectionNodes", - "Elements": [ - "DataCollection" - ] -}, -{ - "Name": "Meta Nodes", - "Version": "0.0.1.80", - "MinimumVersion": "", - "Authors": "John Andrews", - "Url": "https://fileflows.com/", - "Description": "A plugin that contains Meta information nodes used to lookup meta information on files.\r\n\r\nContains nodes to lookup movie information from TheMovieDB, and music information from ID3 tags inside the file.", - "Package": "MetaNodes", - "Elements": [ - "MusicMeta", - "MovieLookup" - ] -}, -{ - "Name": "Video Nodes", - "Version": "0.0.1.80", - "MinimumVersion": "", - "Authors": "John Andrews", - "Url": "https://fileflows.com/", - "Description": "Nodes for processing video files. This plugin contains nodes to convert video files to different formats. Node to parse the video information from a file.", - "Package": "VideoNodes", - "Elements": [ - "VideoFile", - "AudioAdjustVolume", - "AudioNormalization", - "AudioTrackReorder", - "AudioTrackSetLanguage", - "ComskipChapters", - "ComskipRemoveAds", - "FFMPEG", - "RemuxToMKV", - "RemuxToMP4", - "SubtitleExtractor", - "SubtitleRemover", - "Video_H265_AC3", - "VideoEncode", - "VideoScaler", - "DetectBlackBars", - "VideoCodec" - ] -} -]