Class: ActiveSanction::Sources::UnConsolidated
- Extended by:
- T::Sig
- Defined in:
- lib/active_sanction/sources/un_consolidated.rb,
lib/active_sanction/sources/un_consolidated/record.rb
Overview
The United Nations Security Council consolidated list: every individual and entity subject to a UN sanctions regime, in one document.
snapshot = ActiveSanction::Sources[:un_consolidated].new.sync
One file, two record shapes
https://scsanctions.un.org/resources/xml/en/consolidated.xml 2.2 MB
<INDIVIDUALS><INDIVIDUAL> 736 people
<ENTITIES><ENTITY> 275 organizations
Both are read in a single streaming pass. The file is small enough today to have been loaded whole without anyone noticing, which is exactly why it was not: the toolkit this adapter is written against (#15) is the one that will read OFAC's 126 MB advanced XML, and an adapter that quietly depended on holding the document would have to be rewritten then.
The trap in this list
QUALITY appears under both alias elements and means something different
under each. Under <INDIVIDUAL_ALIAS> it grades the alias -- Good or Low
-- which is a matching signal the scorer (#32) penalizes on. Under
<ENTITY_ALIAS> it is not a grade at all; it is a.k.a. or f.k.a.,
which is an alias kind. Reading one as the other silently either throws
away every entity's alias kind or grades 585 organization aliases on a
scale that was never applied to them. Record maps them separately, and
the counts above come from the published file rather than from a guess.
What this adapter does not do
INDIVIDUAL_PLACE_OF_BIRTH, GENDER, TITLE and DESIGNATION have no
home in the canonical model. They are appended to remarks after a marker
rather than dropped -- a place of birth is real screening signal, and
losing it to keep a schema tidy is the wrong trade -- and are left for a
later issue to structure if a matcher turns out to want them.
Instance Attribute Summary collapse
-
#warnings ⇒ Array<Parsers::Warning>
readonly
Records that could not be used.
Attributes inherited from Base
#cache, #fetcher, #instrumenter, #logger
Instance Method Summary collapse
- #initialize(*args, **options) ⇒ void constructor
- #parse(raw) ⇒ Array<Entity>
- #source_version ⇒ String?
Methods inherited from Base
#authority, #column_shapes, #column_tallies, #file_key, #floors, #format, #fresh?, #inspect, #jurisdiction, #key, #parse_argument, published_remarks, #retrieve, #snapshot, #stale?, #sync, #url, #urls
Methods included from Definition
#authority, #declarations, #declared?, #declared_floors, #declared_urls, #file_key, #floor, #floors, #format, #jurisdiction, #key, key!, #licence_notice, #licence_url, #multi_url?, #to_h, #url, #urls
Constructor Details
#initialize(*args, **options) ⇒ void
91 92 93 94 95 96 |
# File 'lib/active_sanction/sources/un_consolidated.rb', line 91 def initialize(*args, **) super @warnings = T.let([], T::Array[Parsers::Warning]) @unmapped = T.let([], T::Array[Parsers::Warning]) @generated_at = T.let(nil, T.nilable(String)) end |
Instance Attribute Details
#warnings ⇒ Array<Parsers::Warning> (readonly)
Records that could not be used. Read after #parse; sync orchestration (#34) reports them.
88 89 90 |
# File 'lib/active_sanction/sources/un_consolidated.rb', line 88 def warnings @warnings end |
Instance Method Details
#parse(raw) ⇒ Array<Entity>
99 100 101 102 103 104 105 |
# File 'lib/active_sanction/sources/un_consolidated.rb', line 99 def parse(raw) reader = LIST.read(raw) entities = build(reader) @generated_at = reader.root[GENERATED_AT] @warnings = reader.warnings + @unmapped entities end |
#source_version ⇒ String?
108 |
# File 'lib/active_sanction/sources/un_consolidated.rb', line 108 def source_version = @generated_at || super |