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