Skip to content

Commit 10899ae

Browse files
committed
Release v.1.5.1
2 parents 47fb726 + a08e88e commit 10899ae

File tree

4 files changed

+257
-133
lines changed

4 files changed

+257
-133
lines changed

.nuget/NuGet.config

Lines changed: 0 additions & 6 deletions
This file was deleted.

IdealPostcodes.cs

Lines changed: 159 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,27 @@
33
using System.ComponentModel;
44
using System.ComponentModel.Composition;
55
using System.Configuration;
6+
using System.Diagnostics.CodeAnalysis;
67
using System.Globalization;
78
using System.Linq;
89
using System.Net;
910

10-
using Rock;
11-
using Rock.Attribute;
12-
using Rock.Address;
1311
using Newtonsoft.Json;
1412
using RestSharp;
1513

16-
namespace com.bricksandmortar.IdealPostcodes
14+
using Rock.Attribute;
15+
using Rock.Address;
16+
using Rock;
17+
18+
namespace com.bricksandmortarstudio.IdealPostcodes.Address
1719
{
1820
/// <summary>
1921
/// The address lookup and geocoding service from <a href="https://ideal-postcodes.co.uk">Ideal Postcodes</a>
2022
/// </summary>
2123
[Description("An address verification and geocoding service from Ideal Postcodes")]
2224
[Export(typeof(VerificationComponent))]
2325
[ExportMetadata("ComponentName", "Ideal Postcodes")]
24-
[TextField("API Key", "Your Ideal Postcodes API Key", true, "", "", 2)]
26+
[TextField("API Key", "Your Ideal Postcodes API key (begins with ak_)", true, "", "", 2)]
2527
public class IdealPostcodes : VerificationComponent
2628
{
2729
/// <summary>
@@ -34,86 +36,44 @@ public class IdealPostcodes : VerificationComponent
3436
/// True/False value of whether the verification was successful or not
3537
/// </returns>
3638

37-
public override bool VerifyLocation( Rock.Model.Location location, bool reVerify, out string result)
39+
public override bool VerifyLocation(Rock.Model.Location location, bool reVerify, out string result)
3840
{
3941
bool verified = false;
4042
result = string.Empty;
4143

42-
// Only verify if location is valid, has not been locked, and
43-
// has either never been attempted or last attempt was in last 30 secs (prev active service failed) or reverifying
44-
if ( location != null &&
45-
!(location.IsGeoPointLocked ?? false) &&
46-
(
47-
!location.GeocodeAttemptedDateTime.HasValue ||
48-
location.GeocodeAttemptedDateTime.Value.CompareTo( RockDateTime.Now.AddSeconds(-30) ) > 0 ||
49-
reVerify
50-
) &&
51-
location.Country == "GB" &&
52-
(string.IsNullOrWhiteSpace(location.Street1) || string.IsNullOrWhiteSpace(location.Street2)))
44+
if (VerifyCheck(location, reVerify))
5345
{
5446

55-
string inputKey = GetAttributeValue( "APIKey" );
56-
var version = new Version( Rock.VersionInfo.VersionInfo.GetRockSemanticVersionNumber() );
57-
string tags = string.Empty;
58-
System.Data.Odbc.OdbcConnectionStringBuilder builder = new System.Data.Odbc.OdbcConnectionStringBuilder(ConfigurationManager.ConnectionStrings["RockContext"].ConnectionString);
59-
object catalog = string.Empty;
60-
if ( builder.TryGetValue("initial catalog", out catalog) )
61-
{
62-
tags = string.Format("{0},{1}", version, catalog);
63-
}
47+
string inputKey = GetAttributeValue("APIKey");
48+
string tags;
49+
CreateTags(out tags);
6450

65-
6651
//Create address that encodes correctly
67-
var addressParts = new string[]
68-
{location.Street1, location.Street2, location.City, location.PostalCode};
69-
string inputAddress = string.Join(" ", addressParts.Where(s => !string.IsNullOrEmpty(s)));
52+
string inputAddress;
53+
CreateInputAddress(location, out inputAddress);
7054

7155
//restsharp API request
7256
var client = new RestClient("https://api.ideal-postcodes.co.uk/");
73-
var request = new RestRequest(Method.GET);
74-
request.RequestFormat = DataFormat.Json;
75-
request.Resource = "v1/addresses/";
76-
request.AddParameter("api_key", inputKey);
77-
request.AddParameter("query", inputAddress);
78-
request.AddParameter("limit", "1");
79-
request.AddParameter("tags", tags);
80-
var response = client.Execute( request );
81-
57+
var request = BuildRequest(inputKey, inputAddress, tags);
58+
var response = client.Execute(request);
59+
8260
if (response.StatusCode == HttpStatusCode.OK)
83-
//Create a series of vars to make decoded response accessible
61+
//Create a series of vars to make decoded response accessible
8462
{
85-
var droot = JsonConvert.DeserializeObject <RootObject>(response.Content);
86-
var dresult = droot.result;
87-
var hitresult = dresult.hits;
88-
if (hitresult.Any())
89-
{
90-
var address = hitresult.FirstOrDefault();
91-
verified = true;
92-
result = string.Format( "UDPRN: {0}", address.udprn );
93-
location.Street1 = address.line_1;
94-
location.Street2 = address.line_2;
95-
if (!string.IsNullOrWhiteSpace(address.dependant_locality) && address.dependant_locality != address.line_2)
96-
{
97-
location.City = address.dependant_locality;
98-
}
99-
else
100-
{
101-
string city = address.post_town;
102-
city = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(city.ToLower());
103-
location.City = city;
104-
}
105-
106-
location.State = address.county;
107-
location.PostalCode = address.postcode;
108-
location.StandardizedDateTime = RockDateTime.Now;
109-
location.SetLocationPointFromLatLong( address.latitude, address.longitude );
110-
location.GeocodedDateTime = RockDateTime.Now;
111-
}
112-
else
113-
{
114-
result = "No match.";
115-
verified = false;
116-
}
63+
var idealResponse = JsonConvert.DeserializeObject<RootObject>(response.Content);
64+
var idealAddress = idealResponse.result.hits;
65+
if (idealAddress.Any())
66+
{
67+
var address = idealAddress.FirstOrDefault();
68+
verified = true;
69+
// ReSharper disable once PossibleNullReferenceException
70+
result = $"Verified by Ideal Postcodes UDPRN: {address.udprn}";
71+
UpdateLocation(location, address);
72+
}
73+
else
74+
{
75+
result = "No match.";
76+
}
11777
}
11878
else
11979
{
@@ -130,57 +90,134 @@ public override bool VerifyLocation( Rock.Model.Location location, bool reVerify
13090

13191
return verified;
13292
}
133-
134-
}
13593

136-
#pragma warning disable
137-
public class Hit
138-
{
139-
public string dependant_locality { get; set; }
140-
public string postcode_type { get; set; }
141-
public string po_box { get; set; }
142-
public string post_town { get; set; }
143-
public string delivery_point_suffix { get; set; }
144-
public string double_dependant_locality { get; set; }
145-
public string su_organisation_indicator { get; set; }
146-
public double longitude { get; set; }
147-
public string department_name { get; set; }
148-
public string district { get; set; }
149-
public string building_name { get; set; }
150-
public string dependant_thoroughfare { get; set; }
151-
public int northings { get; set; }
152-
public string premise { get; set; }
153-
public string postcode_outward { get; set; }
154-
public string postcode_inward { get; set; }
155-
public string sub_building_name { get; set; }
156-
public int eastings { get; set; }
157-
public string postcode { get; set; }
158-
public string country { get; set; }
159-
public int udprn { get; set; }
160-
public string line_3 { get; set; }
161-
public string organisation_name { get; set; }
162-
public string ward { get; set; }
163-
public string county { get; set; }
164-
public string line_1 { get; set; }
165-
public string building_number { get; set; }
166-
public string thoroughfare { get; set; }
167-
public string line_2 { get; set; }
168-
public double latitude { get; set; }
169-
}
94+
private IRestRequest BuildRequest(string inputKey, string inputAddress, string tags)
95+
{
96+
var request = new RestRequest(Method.GET)
97+
{
98+
RequestFormat = DataFormat.Json,
99+
Resource = "v1/addresses/"
100+
};
101+
request.AddParameter("api_key", inputKey);
102+
request.AddParameter("query", inputAddress);
103+
request.AddParameter("limit", "1");
104+
request.AddParameter("tags", tags);
105+
return request;
106+
}
170107

171-
public class Result
172-
{
173-
public int total { get; set; }
174-
public int limit { get; set; }
175-
public int page { get; set; }
176-
public List<Hit> hits { get; set; }
177-
}
108+
public bool VerifyCheck(Rock.Model.Location location, bool reVerify)
109+
{
110+
// Check if the location is valid, has not been locked, and
111+
// has either never been attempted or last attempt was in last 30 secs (prev active service failed) or reverifying
112+
if (location != null &&
113+
!(location.IsGeoPointLocked ?? false) &&
114+
(
115+
!location.GeocodeAttemptedDateTime.HasValue ||
116+
location.GeocodeAttemptedDateTime.Value.CompareTo(RockDateTime.Now.AddSeconds(-30)) > 0 ||
117+
reVerify
118+
) &&
119+
location.Country == "GB" &&
120+
(string.IsNullOrWhiteSpace(location.Street1) || string.IsNullOrWhiteSpace(location.Street2)))
121+
{
122+
return true;
123+
}
124+
else
125+
{
126+
return false;
127+
}
128+
}
178129

179-
public class RootObject
180-
{
181-
public Result result { get; set; }
182-
public int code { get; set; }
183-
public string message { get; set; }
130+
public void CreateTags(out string tags)
131+
{
132+
tags = null;
133+
var version = new Version(Rock.VersionInfo.VersionInfo.GetRockSemanticVersionNumber());
134+
System.Data.Odbc.OdbcConnectionStringBuilder builder = new System.Data.Odbc.OdbcConnectionStringBuilder(ConfigurationManager.ConnectionStrings["RockContext"].ConnectionString);
135+
object catalog;
136+
if (builder.TryGetValue("initial catalog", out catalog))
137+
{
138+
tags = $"{version},{catalog}";
139+
}
140+
}
141+
142+
public void CreateInputAddress(Rock.Model.Location location, out string inputAddress)
143+
{
144+
var addressParts = new string[] { location.Street1, location.Street2, location.City, location.PostalCode };
145+
inputAddress = string.Join(" ", addressParts.Where(s => !string.IsNullOrEmpty(s)));
146+
}
147+
148+
public void UpdateLocation(Rock.Model.Location location, dynamic address)
149+
{
150+
location.Street1 = address.line_1;
151+
location.Street2 = address.line_2;
152+
if (!string.IsNullOrWhiteSpace(address.dependant_locality) && address.dependant_locality != address.line_2)
153+
{
154+
location.City = address.dependant_locality;
155+
}
156+
else
157+
{
158+
string city = address.post_town;
159+
city = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(city.ToLower());
160+
location.City = city;
161+
}
162+
163+
location.State = address.county;
164+
location.PostalCode = address.postcode;
165+
location.StandardizedDateTime = RockDateTime.Now;
166+
location.SetLocationPointFromLatLong(address.latitude, address.longitude);
167+
location.GeocodedDateTime = RockDateTime.Now;
168+
}
169+
170+
171+
[SuppressMessage("ReSharper", "InconsistentNaming")]
172+
public class ResultAddress
173+
{
174+
public string dependant_locality { get; set; }
175+
public string postcode_type { get; set; }
176+
public string po_box { get; set; }
177+
public string post_town { get; set; }
178+
public string delivery_point_suffix { get; set; }
179+
public string double_dependant_locality { get; set; }
180+
public string su_organisation_indicator { get; set; }
181+
public double longitude { get; set; }
182+
public string department_name { get; set; }
183+
public string district { get; set; }
184+
public string building_name { get; set; }
185+
public string dependant_thoroughfare { get; set; }
186+
public int northings { get; set; }
187+
public string premise { get; set; }
188+
public string postcode_outward { get; set; }
189+
public string postcode_inward { get; set; }
190+
public string sub_building_name { get; set; }
191+
public int eastings { get; set; }
192+
public string postcode { get; set; }
193+
public string country { get; set; }
194+
public int udprn { get; set; }
195+
public string line_3 { get; set; }
196+
public string organisation_name { get; set; }
197+
public string ward { get; set; }
198+
public string county { get; set; }
199+
public string line_1 { get; set; }
200+
public string building_number { get; set; }
201+
public string thoroughfare { get; set; }
202+
public string line_2 { get; set; }
203+
public double latitude { get; set; }
204+
}
205+
206+
[SuppressMessage("ReSharper", "InconsistentNaming")]
207+
public class Result
208+
{
209+
public int total { get; set; }
210+
public int limit { get; set; }
211+
public int page { get; set; }
212+
public List<ResultAddress> hits { get; set; }
213+
}
214+
215+
[SuppressMessage( "ReSharper", "InconsistentNaming" )]
216+
public class RootObject
217+
{
218+
public Result result { get; set; }
219+
public int code { get; set; }
220+
public string message { get; set; }
221+
}
184222
}
185-
#pragma warning restore
186-
}
223+
}

0 commit comments

Comments
 (0)