lib/rixml.rb in rixml-0.0.6 vs lib/rixml.rb in rixml-0.1.0

- old
+ new

@@ -1,11 +1,22 @@ # frozen_string_literal: true require 'nokogiri' require 'date' require 'active_support/core_ext/hash/conversions' +require 'active_support/inflector/inflections' class RIXML + class << self + def parse(data) + RIXML.new(Nokogiri::XML(data).root) + end + + def parse_from_file(filename) + parse File.read(filename) + end + end + def initialize(document) @attrs = Hash.from_xml(document.to_s) end def product_id @@ -19,34 +30,20 @@ def publication_date time_str = @attrs.dig('Research', 'Product', 'StatusInfo', 'statusDateTime') || DateTime.now.to_s DateTime.strptime(time_str) end - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/MethodLength def authors org = @attrs.dig('Research', 'Product', 'Source', 'Organization') || {} if org.is_a? Array org = org.find { |v| v['primaryIndicator'] == 'Yes' } || org.first end authors = org.dig('PersonGroup', 'PersonGroupMember') || [] authors = [authors] unless authors.is_a? Array - authors.map do |author| - person = author['Person'] - { - name: person['DisplayName'], - first_name: person['GivenName'], - middle_name: person['MiddleName'], - last_name: person['FamilyName'], - job_title: person['JobTitle'], - email: person['ContactInfo']&.dig('Email')&.downcase - } - end + authors.map { |author| parse_info_from_author(author) } end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/MethodLength def report_info content = @attrs.dig('Research', 'Product', 'Content') { title: content['Title'], @@ -57,53 +54,62 @@ } end def context context = @attrs.dig('Research', 'Product', 'Context') - { companies: RIXML.extract_companies_from_context(context), sectors: RIXML.extract_sectors_from_context(context) } + { + companies: parse_companies_from_context(context), + sectors: parse_sectors_from_context(context), + countries: parse_countries_from_context(context) + } end - def self.parse(data) - RIXML.new(Nokogiri::XML(data).root) + private + + def parse_info_from_author(author) + person = author&.dig('Person') + { + name: person['DisplayName'], + first_name: person['GivenName'], + middle_name: person['MiddleName'], + last_name: person['FamilyName'], + job_title: person['JobTitle'], + email: person['ContactInfo']&.dig('Email')&.downcase + } end - def self.parse_from_file(filename) - parse read_file(filename) + def parse_sectors_from_context(context) + list = context['ProductClassifications'].try(:[], 'SectorIndustry') + return [] if list.nil? + list = [list] unless list.is_a? Array + list.select { |s| s['classificationType'] == 'GICS' }.map do |v| + { code: v['code'].to_i, focus: v['focusLevel'].try(:downcase) == 'yes' } + end end - def self.read_file(filename) - body = ''.dup - File.open(filename, 'r') do |infile| - while (line = infile.gets) - body << line - end + def parse_countries_from_context(context) + [context['ProductClassifications']&.dig('Country')].flatten.map do |country| + { code: country['code'].upcase } end - body end - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/MethodLength - def self.extract_companies_from_context(context) + def parse_companies_from_context(context) companies = [] list = context['IssuerDetails'].try(:[], 'Issuer') return [] if list.nil? list = [list] unless list.is_a? Array list.select { |c| c['issuerType'] == 'Corporate' }.each do |company| - securities = company.dig('SecurityDetails', 'Security', 'SecurityID') - securities = [securities] unless securities.is_a? Array - isin = securities.find { |security| security['idType'] == 'ISIN' } - companies << { isin: isin['idValue'] } unless isin&.dig('idValue').nil? + companies << parse_company_info(company) end companies end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/MethodLength - def self.extract_sectors_from_context(context) - list = context['ProductClassifications'].try(:[], 'SectorIndustry') - return [] if list.nil? - list = [list] unless list.is_a? Array - list.select { |s| s['classificationType'] == 'GICS' }.map do |v| - { code: v['code'].to_i, focus: v['focusLevel'].try(:downcase) == 'yes' } - end + def parse_company_info(company) + security_ids = company.dig('SecurityDetails', 'Security', 'SecurityID') + security_ids = [security_ids] unless security_ids.is_a? Array + ids = security_ids.map do |security_id| + { security_id['idType'].underscore.to_sym => security_id['idValue'] } + end.reduce({}, :merge) + info = { name: (company.dig('IssuerName') || [])['NameValue'] } + info.merge(ids) end end