Class: SecQuery::Filing
- Inherits:
-
Object
- Object
- SecQuery::Filing
- Defined in:
- lib/sec_query/filing.rb
Overview
> SecQuery::Filing
SecQuery::Filing requests and parses filings for any given SecQuery::Entity
Constant Summary collapse
- COLUMNS =
[:cik, :title, :summary, :link, :term, :date, :file_id]
Class Method Summary collapse
- .fetch(uri, &blk) ⇒ Object
- .filing_for_index_row(row) ⇒ Object
- .filings_for_index(index) ⇒ Object
- .find(cik, start = 0, count = 80, args = {}) ⇒ Object
- .for_cik(cik, options = {}, &blk) ⇒ Object
- .for_date(date, &blk) ⇒ Object
- .last(cik, args = {}) ⇒ Object
- .parse(cik, document) ⇒ Object
- .parse_rss(rss, &blk) ⇒ Object
- .recent(options = {}, &blk) ⇒ Object
- .uri_for_cik(cik, start = 0, count = 100) ⇒ Object
- .uri_for_recent(start = 0, count = 100) ⇒ Object
Instance Method Summary collapse
- #content(&error_blk) ⇒ Object
- #detail ⇒ Object
-
#initialize(filing) ⇒ Filing
constructor
A new instance of Filing.
Constructor Details
Class Method Details
.fetch(uri, &blk) ⇒ Object
21 22 23 24 25 |
# File 'lib/sec_query/filing.rb', line 21 def self.fetch(uri, &blk) RestClient::Request.execute(method: :get, url: uri.to_s, timeout: 10) do |response, request, result, &block| parse_rss(response.body, &blk) end end |
.filing_for_index_row(row) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/sec_query/filing.rb', line 71 def self.filing_for_index_row(row) data = row.split(/ /).reject(&:blank?).map(&:strip) data = row.split(/ /).reject(&:blank?).map(&:strip) if data.count == 4 return nil unless data[0] and data[1] and data[2] and data[3] and data[4] data.delete_at(1) if data[1][0] == '/' return nil unless Regexp.new(/\d{8}/).match(data[3]) return nil if data[4] == nil unless data[4][0..3] == 'http' data[4] = "https://www.sec.gov/Archives/#{ data[4] }" end begin Date.parse(data[3]) rescue ArgumentError return nil end Filing.new( term: data[1], cik: data[2], date: Date.parse(data[3]), link: data[4] ) end |
.filings_for_index(index) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/sec_query/filing.rb', line 59 def self.filings_for_index(index) [].tap do |filings| content_section = false index.each_line do |row| content_section = true if row.include?('-------------') next if !content_section || row.include?('------------') filing = filing_for_index_row(row) filings << filing unless filing.nil? end end end |
.find(cik, start = 0, count = 80, args = {}) ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/sec_query/filing.rb', line 131 def self.find(cik, start = 0, count = 80, args={}) temp = {} temp[:url] = SecURI.browse_edgar_uri({cik: cik}) temp[:url][:action] = :getcompany temp[:url][:start] = start temp[:url][:count] = count args.each {|k,v| temp[:url][k]=v } response = Entity.query(temp[:url].output_atom.to_s) document = Nokogiri::HTML(response) parse(cik, document) end |
.for_cik(cik, options = {}, &blk) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/sec_query/filing.rb', line 40 def self.for_cik(cik, = {}, &blk) start = .fetch(:start, 0) count = .fetch(:count, 100) limit = .fetch(:limit, 100) fetch(uri_for_cik(cik, start, count), &blk) start += count return if start >= limit for_cik(cik, { start: start, count: count, limit: limit }, &blk) rescue OpenURI::HTTPError return end |
.for_date(date, &blk) ⇒ Object
52 53 54 55 56 57 |
# File 'lib/sec_query/filing.rb', line 52 def self.for_date(date, &blk) url = SecURI.for_date(date).to_s RestClient::Request.execute(method: :get, url: url, timeout: 10) do |response, request, result, &block| filings_for_index(response.body).each(&blk) end end |
.last(cik, args = {}) ⇒ Object
144 145 146 147 |
# File 'lib/sec_query/filing.rb', line 144 def self.last(cik, args = {}) filings = find(cik, 0, 1, args) filings.is_a?(Array) ? filings.first : nil end |
.parse(cik, document) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/sec_query/filing.rb', line 149 def self.parse(cik, document) filings = [] if document.xpath('//content').to_s.length > 0 document.xpath('//content').each do |e| if e.xpath('//content/accession-number').to_s.length > 0 content = Hash.from_xml(e.to_s)['content'] content[:cik] = cik content[:file_id] = content.delete('accession_nunber') content[:date] = content.delete('filing_date') content[:link] = content.delete('filing_href') content[:term] = content.delete('filing_type') content[:title] = content.delete('form_name') filings << Filing.new(content) end end end filings end |
.parse_rss(rss, &blk) ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/sec_query/filing.rb', line 115 def self.parse_rss(rss, &blk) feed = RSS::Parser.parse(rss, false) feed.entries.each do |entry| filing = Filing.new( cik: entry.title.content.match(/\((\w{10})\)/)[1], file_id: entry.id.content.split('=').last, term: entry.category.term, title: entry.title.content, summary: entry.summary.content, date: DateTime.parse(entry.updated.content.to_s), link: entry.link.href.gsub('-index.htm', '.txt') ) blk.call(filing) end end |
.recent(options = {}, &blk) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/sec_query/filing.rb', line 27 def self.recent( = {}, &blk) start = .fetch(:start, 0) count = .fetch(:count, 100) limit = .fetch(:limit, 100) limited_count = [limit - start, count].min fetch(uri_for_recent(start, limited_count), &blk) start += count return if start >= limit recent({ start: start, count: count, limit: limit }, &blk) rescue OpenURI::HTTPError return end |
.uri_for_cik(cik, start = 0, count = 100) ⇒ Object
104 105 106 107 108 109 110 111 112 113 |
# File 'lib/sec_query/filing.rb', line 104 def self.uri_for_cik(cik, start = 0, count = 100) SecURI.browse_edgar_uri( action: :getcompany, owner: :include, output: :atom, start: start, count: count, CIK: cik ) end |
.uri_for_recent(start = 0, count = 100) ⇒ Object
94 95 96 97 98 99 100 101 102 |
# File 'lib/sec_query/filing.rb', line 94 def self.uri_for_recent(start = 0, count = 100) SecURI.browse_edgar_uri( action: :getcurrent, owner: :include, output: :atom, start: start, count: count ) end |
Instance Method Details
#content(&error_blk) ⇒ Object
168 169 170 171 172 173 174 175 176 177 |
# File 'lib/sec_query/filing.rb', line 168 def content(&error_blk) @content ||= RestClient.get(self.link) rescue RestClient::ResourceNotFound => e puts "404 Resource Not Found: Bad link #{ self.link }" if block_given? error_blk.call(e, self) else raise e end end |
#detail ⇒ Object
17 18 19 |
# File 'lib/sec_query/filing.rb', line 17 def detail @detail ||= FilingDetail.fetch(@link) end |