3
3
using System . ComponentModel ;
4
4
using System . ComponentModel . Composition ;
5
5
using System . Configuration ;
6
+ using System . Diagnostics . CodeAnalysis ;
6
7
using System . Globalization ;
7
8
using System . Linq ;
8
9
using System . Net ;
9
10
10
- using Rock ;
11
- using Rock . Attribute ;
12
- using Rock . Address ;
13
11
using Newtonsoft . Json ;
14
12
using RestSharp ;
15
13
16
- namespace com . bricksandmortar . IdealPostcodes
14
+ using Rock . Attribute ;
15
+ using Rock . Address ;
16
+ using Rock ;
17
+
18
+ namespace com . bricksandmortarstudio . IdealPostcodes . Address
17
19
{
18
20
/// <summary>
19
21
/// The address lookup and geocoding service from <a href="https://ideal-postcodes.co.uk">Ideal Postcodes</a>
20
22
/// </summary>
21
23
[ Description ( "An address verification and geocoding service from Ideal Postcodes" ) ]
22
24
[ Export ( typeof ( VerificationComponent ) ) ]
23
25
[ 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 ) ]
25
27
public class IdealPostcodes : VerificationComponent
26
28
{
27
29
/// <summary>
@@ -34,86 +36,44 @@ public class IdealPostcodes : VerificationComponent
34
36
/// True/False value of whether the verification was successful or not
35
37
/// </returns>
36
38
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 )
38
40
{
39
41
bool verified = false ;
40
42
result = string . Empty ;
41
43
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 ) )
53
45
{
54
46
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 ) ;
64
50
65
-
66
51
//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 ) ;
70
54
71
55
//restsharp API request
72
56
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
+
82
60
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
84
62
{
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
+ }
117
77
}
118
78
else
119
79
{
@@ -130,57 +90,134 @@ public override bool VerifyLocation( Rock.Model.Location location, bool reVerify
130
90
131
91
return verified ;
132
92
}
133
-
134
- }
135
93
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
+ }
170
107
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
+ }
178
129
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
+ }
184
222
}
185
- #pragma warning restore
186
- }
223
+ }
0 commit comments