Total Complexity | 90 |
Total Lines | 357 |
Duplicated Lines | 14.01 % |
Changes | 3 | ||
Bugs | 0 | Features | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like LocationElementSchemaNode often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | # -*- coding: utf-8 -*- |
||
43 | class LocationElementSchemaNode(colander.MappingSchema): |
||
44 | id = colander.SchemaNode( |
||
45 | colander.Integer(), |
||
46 | missing=None |
||
47 | ) |
||
48 | |||
49 | type = colander.SchemaNode( |
||
50 | colander.String(), |
||
51 | validator=colander.Length(1, 250) |
||
52 | ) |
||
53 | |||
54 | provincie = ProvincieSchemaNode( |
||
55 | missing={} |
||
56 | ) |
||
57 | |||
58 | gemeente = GemeenteSchemaNode( |
||
59 | missing={} |
||
60 | ) |
||
61 | |||
62 | straat = colander.SchemaNode( |
||
63 | colander.String(), |
||
64 | validator=colander.Length(1, 100), |
||
65 | missing=None |
||
66 | ) |
||
67 | |||
68 | straat_id = colander.SchemaNode( |
||
69 | colander.Integer(), |
||
70 | missing=None |
||
71 | ) |
||
72 | |||
73 | huisnummer = colander.SchemaNode( |
||
74 | colander.String(), |
||
75 | validator=colander.Length(1, 20), |
||
76 | missing=None |
||
77 | ) |
||
78 | |||
79 | huisnummer_id = colander.SchemaNode( |
||
80 | colander.Integer(), |
||
81 | missing=None |
||
82 | ) |
||
83 | |||
84 | subadres = colander.SchemaNode( |
||
85 | colander.String(), |
||
86 | validator=colander.Length(1, 20), |
||
87 | missing=None |
||
88 | ) |
||
89 | |||
90 | subadres_id = colander.SchemaNode( |
||
91 | colander.Integer(), |
||
92 | missing=None |
||
93 | ) |
||
94 | |||
95 | postcode = colander.SchemaNode( |
||
96 | colander.String(), |
||
97 | validator=colander.Length(1, 20), |
||
98 | missing=None |
||
99 | ) |
||
100 | |||
101 | land = colander.SchemaNode( |
||
102 | colander.String(), |
||
103 | validator=colander.Length(1, 100), |
||
104 | missing='BE' |
||
105 | ) |
||
106 | |||
107 | perceel = CadasterSchemaNode( |
||
108 | missing=None |
||
109 | ) |
||
110 | |||
111 | omschrijving = colander.SchemaNode( |
||
112 | colander.String(), |
||
113 | validator=colander.Length(1, 250), |
||
114 | missing=None |
||
115 | ) |
||
116 | |||
117 | def preparer(self, locatie_element): |
||
118 | if locatie_element is None or not locatie_element: |
||
119 | return null # pragma: no cover |
||
120 | request = self.bindings['request'] |
||
121 | crab_gateway = request.crab_gateway() |
||
122 | capakey_gateway = request.capakey_gateway() |
||
123 | locatie_element_type = '' |
||
124 | if 'type' in locatie_element: |
||
125 | locatie_element_type = locatie_element.get('type') |
||
126 | if 'land' in locatie_element and locatie_element.get('land').upper() == 'BE': |
||
127 | if locatie_element_type == 'https://id.erfgoed.net/vocab/ontology#LocatieElementAdres': |
||
128 | locatie_element = self._prepare_locatie_adres(crab_gateway, locatie_element) |
||
129 | if locatie_element_type == 'https://id.erfgoed.net/vocab/ontology#LocatieElementPerceel': |
||
130 | locatie_element = self._prepare_locatie_perceel(capakey_gateway, crab_gateway, locatie_element) |
||
131 | if locatie_element_type == 'https://id.erfgoed.net/vocab/ontology#LocatieElementOpenbaarDomein': |
||
132 | locatie_element = self._prepare_locatie(crab_gateway, locatie_element) |
||
133 | if locatie_element_type == 'https://id.erfgoed.net/vocab/ontology#LocatieElement': |
||
134 | locatie_element = self._prepare_locatie(crab_gateway, locatie_element) |
||
135 | else: |
||
136 | locatie_element['gemeente']['id'] = None |
||
137 | locatie_element['straat_id'] = None |
||
138 | locatie_element['huisnummer_id'] = None |
||
139 | locatie_element['subadres_id'] = None |
||
140 | if 'land' in locatie_element: |
||
141 | locatie_element['land'] = locatie_element.get('land').upper() |
||
142 | return locatie_element |
||
143 | |||
144 | def validator(self, node, locatie_element): |
||
145 | request = self.bindings['request'] |
||
146 | crab_gateway = request.crab_gateway() |
||
147 | capakey_gateway = request.capakey_gateway() |
||
148 | locatie_element_type = '' |
||
149 | land = None |
||
150 | if 'type' in locatie_element: |
||
151 | locatie_element_type = locatie_element.get('type') |
||
152 | if 'land' in locatie_element: |
||
153 | land = locatie_element.get('land') |
||
154 | try: |
||
155 | pycountry.countries.get(alpha2=land) |
||
156 | except KeyError: |
||
157 | raise colander.Invalid( |
||
158 | node, |
||
159 | 'ongeldige landcode %s, dit is geen ISO 3166 code' % |
||
160 | land |
||
161 | ) |
||
162 | if land == 'BE': |
||
163 | if locatie_element_type == 'https://id.erfgoed.net/vocab/ontology#LocatieElementAdres': |
||
164 | self._validate_locatie_adres(crab_gateway, locatie_element, node) |
||
165 | if locatie_element_type == 'https://id.erfgoed.net/vocab/ontology#LocatieElementPerceel': |
||
166 | self._validate_locatie_perceel(capakey_gateway, locatie_element, node) |
||
167 | if locatie_element_type == 'https://id.erfgoed.net/vocab/ontology#LocatieElementOpenbaarDomein': |
||
168 | self._validate_locatie_openbaar_domein(locatie_element, node) |
||
169 | if locatie_element_type == 'https://id.erfgoed.net/vocab/ontology#LocatieElement': |
||
170 | self._validate_locatie(locatie_element, node) |
||
171 | |||
172 | @staticmethod |
||
173 | def _prepare_locatie_adres(crab_gateway, locatie_element): |
||
174 | if locatie_element.get('gemeente', {}).get('id', None) is None: |
||
175 | if locatie_element.get('gemeente', {}).get('naam', None) is None: |
||
176 | return locatie_element |
||
177 | gemeente = locatie_element.get('gemeente', {}).get('naam') |
||
178 | gewest_ids = [2, 1, 3] |
||
179 | for gewest_id in gewest_ids: |
||
180 | gemeenten = crab_gateway.list_gemeenten(gewest_id) |
||
181 | gemeente_val = next((g for g in gemeenten if g.naam.lower() == gemeente.lower()), None) |
||
182 | if gemeente_val: |
||
183 | locatie_element['gemeente']['id'] = gemeente_val.id |
||
184 | break |
||
185 | if locatie_element.get('gemeente', {}).get('id', None) is None: |
||
186 | return locatie_element |
||
187 | gemeente_id = locatie_element.get('gemeente', {}).get('id', None) |
||
188 | straat_id = locatie_element.get('straat_id', None) |
||
189 | straat = locatie_element.get('straat', None) |
||
190 | huisnummer_id = locatie_element.get('huisnummer_id', None) |
||
191 | huisnummer = locatie_element.get('huisnummer', None) |
||
192 | subadres_id = locatie_element.get('subadres_id', None) |
||
193 | subadres = locatie_element.get('subadres', None) |
||
194 | try: |
||
195 | gemeente = crab_gateway.get_gemeente_by_id(gemeente_id) |
||
196 | except (GatewayRuntimeException, AttributeError): |
||
197 | locatie_element['gemeente']['naam'] = None |
||
198 | return locatie_element |
||
199 | if gemeente: |
||
200 | locatie_element['gemeente']['naam'] = "" + gemeente.naam |
||
201 | locatie_element['gemeente']['niscode'] = gemeente.niscode |
||
202 | locatie_element['provincie']['niscode'] = gemeente.provincie.niscode |
||
203 | locatie_element['provincie']['naam'] = gemeente.provincie.naam |
||
204 | if straat_id: |
||
205 | straat_val = next((s for s in gemeente.straten if s.id == straat_id), None) |
||
206 | if straat_val: |
||
207 | locatie_element['straat'] = "" + straat_val.label |
||
208 | num_val = process_huisnummer(locatie_element, huisnummer_id, huisnummer, straat_val) |
||
209 | if num_val: |
||
210 | process_subadres(locatie_element, subadres_id, subadres, num_val) |
||
211 | if not straat_id and straat: |
||
212 | straat_val = next((s for s in gemeente.straten if s.label.lower() == straat.lower()), None) |
||
213 | if straat_val: |
||
214 | locatie_element['straat_id'] = straat_val.id |
||
215 | num_val = process_huisnummer(locatie_element, huisnummer_id, huisnummer, straat_val) |
||
216 | if num_val: |
||
217 | process_subadres(locatie_element, subadres_id, subadres, num_val) |
||
218 | return locatie_element |
||
219 | |||
220 | @staticmethod |
||
221 | def _prepare_locatie_perceel(capakey_gateway, crab_gateway, locatie_element): |
||
222 | try: |
||
223 | kadastrale_afdelingen = capakey_gateway.list_kadastrale_afdelingen() |
||
224 | capakey = locatie_element['perceel']['capakey'] |
||
225 | afdeling_niscode = int(capakey[0:5]) |
||
226 | afdeling = next((afd for afd in kadastrale_afdelingen if afd.id == afdeling_niscode), None) |
||
227 | if afdeling: |
||
228 | locatie_element['perceel']['sectie'] = capakey[5:6] |
||
229 | locatie_element['perceel']['perceel'] = capakey[6:] |
||
230 | locatie_element['perceel']['afdeling'] = afdeling.naam |
||
231 | gemeente = crab_gateway.get_gemeente_by_niscode(afdeling.gemeente.id) |
||
232 | locatie_element['gemeente']['id'] = gemeente.id |
||
233 | locatie_element['gemeente']['naam'] = gemeente.naam |
||
234 | locatie_element['gemeente']['niscode'] = afdeling.gemeente.id |
||
235 | locatie_element['provincie']['niscode'] = gemeente.provincie.niscode |
||
236 | locatie_element['provincie']['naam'] = gemeente.provincie.naam |
||
237 | except (GatewayRuntimeException, AttributeError, GatewayResourceNotFoundException) as e: |
||
238 | # couldn't prepare data , skipping |
||
239 | pass |
||
240 | return locatie_element |
||
241 | |||
242 | @staticmethod |
||
243 | def _prepare_locatie(crab_gateway, locatie_element): |
||
244 | gemeente = None |
||
245 | gemeente_id = locatie_element.get('gemeente', {}).get('id', None) |
||
246 | gemeente_niscode = locatie_element.get('gemeente', {}).get('niscode', None) |
||
247 | gemeente_naam = locatie_element.get('gemeente', {}).get('naam', None) |
||
248 | if gemeente_id: |
||
249 | try: |
||
250 | gemeente = crab_gateway.get_gemeente_by_id(gemeente_id) |
||
251 | except (GatewayRuntimeException, AttributeError): |
||
252 | gemeente = None |
||
253 | if gemeente is None and gemeente_niscode: |
||
254 | try: |
||
255 | gemeente = crab_gateway.get_gemeente_by_niscode(gemeente_niscode) |
||
256 | except (GatewayRuntimeException, AttributeError): |
||
257 | gemeente = None |
||
258 | if gemeente is None and gemeente_naam: |
||
259 | gewest_ids = [2, 1, 3] |
||
260 | for gewest_id in gewest_ids: |
||
261 | try: |
||
262 | gemeenten = crab_gateway.list_gemeenten(gewest_id) |
||
263 | gemeente = next((g for g in gemeenten if g.naam.lower() == gemeente_naam.lower()), None) |
||
264 | if gemeente: |
||
265 | break |
||
266 | except (GatewayRuntimeException, AttributeError): # pragma no cover |
||
267 | gemeente = None |
||
268 | if gemeente: |
||
269 | locatie_element['gemeente']['id'] = gemeente.id |
||
270 | locatie_element['gemeente']['naam'] = gemeente.naam |
||
271 | locatie_element['gemeente']['niscode'] = gemeente.niscode |
||
272 | locatie_element['provincie']['niscode'] = gemeente.provincie.niscode |
||
273 | locatie_element['provincie']['naam'] = gemeente.provincie.naam |
||
274 | else: |
||
275 | locatie_element['gemeente']['id'] = None |
||
276 | return locatie_element |
||
277 | |||
278 | @staticmethod |
||
279 | def _validate_provincie_gemeente(locatie_element, node): |
||
280 | gemeente = locatie_element.get('gemeente', {}).get('naam', None) |
||
281 | gemeente_id = locatie_element.get('gemeente', {}).get('id', None) |
||
282 | gemeente_niscode = locatie_element.get('gemeente', {}).get('niscode', None) |
||
283 | provincie = locatie_element.get('provincie', {}).get('naam', None) |
||
284 | provincie_niscode = locatie_element.get('provincie', {}).get('niscode', None) |
||
285 | if gemeente_id is None: |
||
286 | raise colander.Invalid( |
||
287 | node, |
||
288 | 'geen correcte gemeente_id gevonden voor de gemeente {0}'.format(gemeente) |
||
289 | ) |
||
290 | if gemeente is None: # if gemeente is still None here, the gemeente_id was incorrect |
||
291 | raise colander.Invalid( |
||
292 | node, |
||
293 | 'ongeldig gemeente_id {0}'.format(gemeente_id) |
||
294 | ) |
||
295 | if gemeente_niscode is None: # pragma no cover # normally the first 2 checks will fail in this case |
||
296 | raise colander.Invalid( |
||
297 | node, |
||
298 | 'ongeldige gemeente_niscode {0}'.format(gemeente_niscode) |
||
299 | ) |
||
300 | if provincie is None: # pragma no cover # normally the first 2 checks will fail in this case |
||
301 | raise colander.Invalid( |
||
302 | node, |
||
303 | 'ongeldige provincie {0}'.format(provincie) |
||
304 | ) |
||
305 | if provincie_niscode is None: # pragma no cover # normally the first 2 checks will fail in this case |
||
306 | raise colander.Invalid( |
||
307 | node, |
||
308 | 'ongeldige provincie_niscode {0}'.format(provincie_niscode) |
||
309 | ) |
||
310 | |||
311 | def _validate_locatie_perceel(self, capakey_gateway, locatie_element, node): |
||
312 | self._validate_provincie_gemeente(locatie_element, node) |
||
313 | kadastrale_afdelingen = capakey_gateway.list_kadastrale_afdelingen() |
||
314 | capakey = locatie_element['perceel']['capakey'] |
||
315 | afdeling_niscode = int(capakey[0:5]) |
||
316 | afdeling = next((afd for afd in kadastrale_afdelingen if afd.id == afdeling_niscode), None) |
||
317 | if afdeling is None: |
||
318 | raise colander.Invalid( |
||
319 | node, |
||
320 | 'ongeldige kadastrale afdeling voor capakey {0}'.format(capakey) |
||
321 | ) |
||
322 | |||
323 | def _validate_locatie_openbaar_domein(self, locatie_element, node): |
||
324 | self._validate_provincie_gemeente(locatie_element, node) |
||
325 | |||
326 | def _validate_locatie(self, locatie_element, node): |
||
327 | self._validate_provincie_gemeente(locatie_element, node) |
||
328 | |||
329 | def _validate_locatie_adres(self, crab_gateway, locatie_element, node): |
||
330 | self._validate_provincie_gemeente(locatie_element, node) |
||
331 | gemeente_id = locatie_element.get('gemeente', {}).get('id', None) |
||
332 | straat_id = locatie_element.get('straat_id', None) |
||
333 | huisnummer_id = locatie_element.get('huisnummer_id', None) |
||
334 | postcode = locatie_element.get('postcode', None) |
||
335 | subadres_id = locatie_element.get('subadres_id', None) |
||
336 | View Code Duplication | if straat_id is not None: |
|
|
|||
337 | gemeente = crab_gateway.get_gemeente_by_id(gemeente_id) |
||
338 | try: |
||
339 | straat = crab_gateway.get_straat_by_id(straat_id) |
||
340 | except (GatewayRuntimeException, AttributeError): |
||
341 | raise colander.Invalid( |
||
342 | node, |
||
343 | 'ongeldig straat_id' |
||
344 | ) |
||
345 | if straat.gemeente_id != gemeente_id: |
||
346 | raise colander.Invalid( |
||
347 | node, |
||
348 | 'de straat %s met id %s ligt niet in gemeente %s' % |
||
349 | (locatie_element.get('straat', ''), straat_id, gemeente.naam) |
||
350 | ) |
||
351 | if huisnummer_id is not None: |
||
352 | try: |
||
353 | huisnummer = crab_gateway.get_huisnummer_by_id(huisnummer_id) |
||
354 | except (GatewayRuntimeException, AttributeError): |
||
355 | raise colander.Invalid( |
||
356 | node, |
||
357 | 'ongeldig huisnummer_id' |
||
358 | ) |
||
359 | if huisnummer.straat_id != straat_id: |
||
360 | raise colander.Invalid( |
||
361 | node, |
||
362 | 'het huisnummer %s met id %s ligt niet in straat %s' % |
||
363 | (locatie_element.get('huisnummer', ''), huisnummer_id, straat.label) |
||
364 | ) |
||
365 | if postcode is not None: |
||
366 | postkanton = crab_gateway.get_postkanton_by_huisnummer(huisnummer_id) |
||
367 | if postcode != str(postkanton.id): |
||
368 | raise colander.Invalid( |
||
369 | node, |
||
370 | 'postcode %s is niet correct voor dit adres, mogelijke postcode is %s' % |
||
371 | (postcode, postkanton.id) |
||
372 | ) |
||
373 | if subadres_id is not None: |
||
374 | try: |
||
375 | subadres = crab_gateway.get_subadres_by_id(subadres_id) |
||
376 | except (GatewayRuntimeException, AttributeError): |
||
377 | raise colander.Invalid( |
||
378 | node, |
||
379 | 'ongeldig subadres_id' |
||
380 | ) |
||
381 | if subadres.huisnummer_id != huisnummer_id: |
||
382 | raise colander.Invalid( |
||
383 | node, |
||
384 | 'het subadres %s met id %s ligt niet op huisnummer %s' % |
||
385 | (locatie_element.get('subadres', ''), subadres_id, huisnummer.huisnummer) |
||
386 | ) |
||
387 | if straat_id is None and huisnummer_id is not None: |
||
388 | raise colander.Invalid( |
||
389 | node, |
||
390 | 'als er een huisnummer_id wordt gegeven, moet men ook het straat_id invullen' |
||
391 | ) |
||
392 | if huisnummer_id is None and postcode is not None: |
||
393 | postkantons = crab_gateway.list_postkantons_by_gemeente(gemeente_id) |
||
394 | postkantons = [str(pk.id) for pk in postkantons] |
||
395 | if postcode not in postkantons: |
||
396 | raise colander.Invalid( |
||
397 | node, |
||
398 | 'postcode %s is niet correct voor dit adres, mogelijke postcode(s) zijn %s' % |
||
399 | (postcode, postkantons) |
||
400 | ) |
||
401 |