Skip to content

Commit a8b3536

Browse files
committed
Mail settings config and fix bugs with querystrings
1 parent 6e531bd commit a8b3536

File tree

14 files changed

+151
-88
lines changed

14 files changed

+151
-88
lines changed

README.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,28 @@ business entities and your data layer. Useful for pagination as well.
6666

6767
### Mailbot
6868

69-
A multithreaded SMTP queued mail sender, has a throttle based on Google Apps maximums for mail frequency sent by a single account.
69+
A multithreaded SMTP queued mail sender, has a configurable throttle for mail frequency sent by a single account.
70+
71+
**Configuration**
72+
73+
```json
74+
{
75+
"Devlord.Utilities": {
76+
"GoogleMapsApiKey": "",
77+
"MailSettings": [
78+
{
79+
"Name": "Gmail",
80+
"SmtpServer": "mail.google.com",
81+
"SmtpPort": 587,
82+
"SmtpPassword": "",
83+
"MaxPerMinute": 500,
84+
"MaxPerHour": 500,
85+
"MaxPerDay": 500
86+
}
87+
]
88+
}
89+
}
90+
```
7091

7192
### Crypt
7293

@@ -98,4 +119,4 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
98119

99120
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
100121

101-
Contact [lorddev](https://github.com/lorddev) on GitHub or [@devlords](https://twitter.com/devlords) on Twitter.
122+
Contact [lorddev](https://github.com/lorddev) on GitHub or [@devlord@fosstodon.org](https://fosstodon.org/@devlord) on Mastodon.

src/Devlord.Utilities/ApiCall.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Net;
44
using System.Net.Http;
@@ -76,7 +76,7 @@ public virtual void Dispose()
7676

7777
public virtual IApiResult<dynamic> Execute<T>() where T : class
7878
{
79-
_endPoint += BuildQueryString();
79+
_endPoint = AppendQueryString(_endPoint);
8080
return Execute<T>(new Uri(_endPoint));
8181
}
8282

@@ -103,19 +103,19 @@ public virtual IApiResult<dynamic> Execute<T>(Uri endPoint) where T : class
103103
{
104104
var stringContent = new StringContent(serialize(Payload));
105105
stringContent.Headers.ContentType = new MediaTypeHeaderValue(format) { CharSet = "utf-8" };
106-
response = _client.PutAsync(_endPoint, stringContent).Result;
106+
response = _client.PutAsync(endPoint, stringContent).Result;
107107
break;
108108
}
109109
case "POST":
110110
{
111111
var stringContent = new StringContent(serialize(Payload));
112112
stringContent.Headers.ContentType = new MediaTypeHeaderValue(format) { CharSet = "utf-8" };
113-
response = _client.PostAsync(_endPoint, stringContent).Result;
113+
response = _client.PostAsync(endPoint, stringContent).Result;
114114
break;
115115
}
116116
default:
117117
// Assume "GET"
118-
response = _client.GetAsync(_endPoint).Result;
118+
response = _client.GetAsync(endPoint).Result;
119119
break;
120120
}
121121

@@ -148,7 +148,7 @@ public virtual IApiResult<dynamic> Execute<T>(Uri endPoint) where T : class
148148

149149
#region Methods
150150

151-
protected string BuildQueryString()
151+
protected string AppendQueryString(string original)
152152
{
153153
var sb = new StringBuilder();
154154

@@ -166,7 +166,8 @@ protected string BuildQueryString()
166166
}
167167

168168
string qs2 = sb.ToString();
169-
return "?" + qs2;
169+
if (original.Contains('?')) return original + "&" + qs2;
170+
return original + "?" + qs2;
170171
}
171172

172173
protected virtual void Dispose(bool disposing)

src/Devlord.Utilities/Devlord.Utilities.csproj

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
66
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
77
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
8-
<Version>5.1.37</Version>
8+
<Version>6.0.0</Version>
99
<Company>Devlords Cooperative</Company>
1010
<Authors>devlord</Authors>
1111
<PackageProjectUrl>https://github.com/lorddev/utilities</PackageProjectUrl>
12-
<Copyright>Copyright © 2017 Aaron Lord</Copyright>
12+
<Copyright>Copyright © 2022 Aaron Lord</Copyright>
1313
<PackageLicenseUrl>https://raw.githubusercontent.com/lorddev/utilities/master/LICENSE</PackageLicenseUrl>
1414
<PackageIconUrl>https://raw.githubusercontent.com/lorddev/devlords-org/develop/Image.png</PackageIconUrl>
1515
<RepositoryUrl>https://github.com/lorddev/utilities</RepositoryUrl>
@@ -46,16 +46,6 @@
4646
<PackageReference Include="System.Xml.XmlSerializer" Version="4.3.0" />
4747
<PackageReference Include="System.Runtime.Serialization.Xml" Version="4.3.0" />
4848
</ItemGroup>
49-
<ItemGroup Condition="'$(TargetFramework)'=='net451' Or '$(TargetFramework)'=='net462'">
50-
<PackageReference Include="elmah" Version="1.2.2" />
51-
<Reference Include="System" />
52-
<Reference Include="System.Net" />
53-
<Reference Include="System.Net.Http" />
54-
<Reference Include="System.Web" />
55-
<Reference Include="System.Xml.Linq" />
56-
<Reference Include="System.Data" />
57-
<Reference Include="System.Xml" />
58-
</ItemGroup>
5949
<ItemGroup>
6050
<Compile Update="Resources\ExceptionText.Designer.cs">
6151
<DesignTime>True</DesignTime>
@@ -70,7 +60,6 @@
7060
</EmbeddedResource>
7161
</ItemGroup>
7262
<ItemGroup>
73-
<DotNetCliToolReference Include="dotnet-bump" Version="1.0.1" />
7463
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="1.0.0" />
7564
</ItemGroup>
7665
<ItemGroup>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// --------------------------------------------------------------------------------------------------------------------
2+
// <copyright file="DevlordMailSettings.cs" company="Lord Design">
3+
// © 2022 Lord Design
4+
// </copyright>
5+
// <license type="GPL-3.0">
6+
// You may use freely and commercially without modification; if you make changes, please share back to the
7+
// community.
8+
// </license>
9+
// <author>Aaron Lord</author>
10+
// --------------------------------------------------------------------------------------------------------------------
11+
12+
namespace Devlord.Utilities
13+
{
14+
public class DevlordMailSettings
15+
{
16+
public string Name { get; set; }
17+
public int SmtpPort { get; set; }
18+
public string SmtpLogin { get; set; }
19+
public string SmtpPassword { get; set; }
20+
public string SmtpServer { get; set; }
21+
public int MaxPerMinute { get; set; }
22+
public int MaxPerHour { get; set; }
23+
public int MaxPerDay { get; set; }
24+
}
25+
}

src/Devlord.Utilities/DevlordOptions.cs

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,7 @@ namespace Devlord.Utilities
2121
public class DevlordOptions
2222
{
2323
public string GoogleMapsApiKey { get; set; }
24-
private static readonly IConfiguration _configuration = GetConfig();
2524

26-
public static DevlordOptions Default { get; } = new DevlordOptions();
27-
28-
public int SmtpPort => int.Parse(GetValue("SmtpPort"));
29-
public string SmtpLogin => GetValue("SmtpLogin");
30-
public string SmtpPassword => GetValue("SmtpPassword");
31-
public string SmtpServer { get; set; }
32-
33-
private static IConfiguration GetConfig()
34-
{
35-
var builder = new ConfigurationBuilder()
36-
.SetBasePath(AppContext.BaseDirectory)
37-
.AddJsonFile("appsettings.json",
38-
true,
39-
true);
40-
return builder.Build();
41-
}
42-
43-
private static string GetValue(string propertyName)
44-
{
45-
var value = _configuration["Devlord.Utilities:" + propertyName];
46-
if (value == null)
47-
{
48-
throw new SettingNotFoundException(propertyName);
49-
}
50-
return value;
51-
}
25+
public DevlordMailSettings[] MailSettings { get; set; }
5226
}
5327
}

src/Devlord.Utilities/DevlordSettingsExtension.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
// <author>Aaron Lord</author>
1010
// --------------------------------------------------------------------------------------------------------------------
1111

12-
using Devlord.Utilities;
1312
using Microsoft.Extensions.Configuration;
13+
using Microsoft.Extensions.DependencyInjection;
1414

15-
namespace Microsoft.Extensions.DependencyInjection
15+
namespace Devlord.Utilities
1616
{
1717
public static class DevlordSettingsExtension
1818
{
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// --------------------------------------------------------------------------------------------------------------------
2+
// <copyright file="DevlordConfigurationException.cs" company="Lord Design">
3+
// © 2022 Lord Design
4+
// </copyright>
5+
// <license type="GPL-3.0">
6+
// You may use freely and commercially without modification; if you make changes, please share back to the
7+
// community.
8+
// </license>
9+
// <author>Aaron Lord</author>
10+
// --------------------------------------------------------------------------------------------------------------------
11+
12+
using System;
13+
using System.Runtime.Serialization;
14+
15+
namespace Devlord.Utilities.Exceptions
16+
{
17+
18+
[Serializable]
19+
public class DevlordConfigurationException : Exception
20+
{
21+
public DevlordConfigurationException(string s) : base(s)
22+
{
23+
}
24+
25+
protected DevlordConfigurationException(SerializationInfo info, StreamingContext context) : base(info, context)
26+
{
27+
28+
}
29+
}
30+
}

src/Devlord.Utilities/MailbotFactory.cs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
// --------------------------------------------------------------------------------------------------------------------
1111

1212
using System.Collections.Generic;
13+
using System.Linq;
1314
using System.Runtime.CompilerServices;
15+
using Devlord.Utilities.Exceptions;
1416
using Microsoft.Extensions.Options;
1517

1618
[assembly: InternalsVisibleTo("Devlord.Utilities.Tests")]
@@ -33,30 +35,32 @@ public MailbotFactory(IOptionsMonitor<DevlordOptions> options)
3335
/// <summary>
3436
/// Gets the instance.
3537
/// </summary>
36-
public Mailbot GetMailbot(string smtpServer)
38+
public Mailbot GetMailbot(string name)
3739
{
38-
smtpServer = smtpServer.ToLower();
3940
lock (DictionaryLock)
4041
{
41-
if (Instances.ContainsKey(smtpServer))
42+
if (Instances.ContainsKey(name))
4243
{
43-
return Instances[smtpServer];
44+
return Instances[name];
4445
}
4546

47+
var thisOptions = _options.MailSettings.FirstOrDefault(n => n.Name == name);
48+
49+
if (thisOptions == null)
50+
{
51+
throw new DevlordConfigurationException($"Missing mail options for name {name}");
52+
}
53+
4654
var instance = new Mailbot
4755
{
48-
SmtpServer = smtpServer,
49-
SmtpPort = _options.SmtpPort,
50-
SmtpLogin = _options.SmtpLogin,
51-
EncryptedPassword = _options.SmtpPassword
56+
SmtpServer = thisOptions.SmtpServer,
57+
SmtpPort = thisOptions.SmtpPort,
58+
SmtpLogin = thisOptions.SmtpLogin,
59+
EncryptedPassword = thisOptions.SmtpPassword,
60+
Throttles = new Throttles(thisOptions.MaxPerMinute, thisOptions.MaxPerHour, thisOptions.MaxPerDay)
5261
};
53-
if (smtpServer == "smtp.gmail.com")
54-
{
55-
instance.Throttles = new GmailThrottles();
56-
}
5762

58-
instance.SmtpServer = smtpServer;
59-
Instances.Add(smtpServer, instance);
63+
Instances.Add(name, instance);
6064
return instance;
6165
}
6266
}

src/Devlord.Utilities/Throttles.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public Throttles() : this(180, 3600, 1000)
2222
/// <summary>
2323
/// Initializes a new instance of the <see cref="Throttles" /> class.
2424
/// </summary>
25-
protected Throttles(int min, int hour, int day)
25+
public Throttles(int min, int hour, int day)
2626
{
2727
MinuteThrottle = new MailThrottle { Interval = ThrottleInterval.Minute, Limit = min };
2828
HourlyThrottle = new MailThrottle { Interval = ThrottleInterval.Hour, Limit = hour };

src/Devlord.Utilities/WebApiCall.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public override void Dispose()
4242

4343
public override IApiResult<dynamic> Execute<T>()
4444
{
45-
string endPoint = BuildEndpoint() + BuildQueryString();
45+
string endPoint = AppendQueryString(BuildEndpoint());
4646
return base.Execute<T>(new Uri(endPoint));
4747
}
4848

0 commit comments

Comments
 (0)